public Task WaitForAsync(string host, string serverName, string tagID, T waitFor, ILog logger) where T:struct { TaskCompletionSource tcs = new TaskCompletionSource(); EasyDAClient opcComponent = new EasyDAClient(); opcComponent.Isolated = true; opcComponent.InstanceParameters.Mode.AllowAsynchronousMethod = false; opcComponent.ItemChanged += (s, e) => { try { if (e.Vtq != null) { if (e.Vtq.Quality.IsGood()) { string itemId = e.ItemDescriptor.ItemId; if (e.Vtq.Value is T && waitFor.Equals(e.Vtq.Value)) { tcs.SetResult((T)e.Vtq.Value); opcComponent.UnsubscribeAllItems(); opcComponent.Dispose(); } else if (e.Vtq.Value is Int16 || (Int16)e.Vtq.Value > 90) { if ((Int16)e.Vtq.Value == (Int16)MES.Constants.RESULTCODE.RECIPE_ERROR) { tcs.SetException(new MES.Common.Exceptions.PlcErrorCodeException(MES.Constants.RESULTCODE.RECIPE_ERROR, "Unknown recipe")); opcComponent.UnsubscribeAllItems(); opcComponent.Dispose(); } if ((Int16)e.Vtq.Value == (Int16)MES.Constants.RESULTCODE.OUT_OF_MATERIAL) { tcs.SetException(new MES.Common.Exceptions.PlcErrorCodeException(MES.Constants.RESULTCODE.OUT_OF_MATERIAL, "Out of material")); opcComponent.UnsubscribeAllItems(); opcComponent.Dispose(); } } } else { logger.DebugFormat("Quality WaitForAsync : {0}", e.Vtq.Quality.StatusBitField); } } } catch(Exception ex) { logger.Fatal("OPCReader.WaitForAsync", ex); throw; } }; opcComponent.SubscribeItem(host, serverName, tagID, 300); return tcs.Task; }