在后台工作程序中调用异步方法不会单独报告进度

时间:2018-02-21 02:13:47

标签: c# async-await backgroundworker

我正在调用一个返回Task<的异步方法。 CurrentCartridgeStatus>来自背景工作者。事情是,直到CurrentCartridgeStatus改变其我想继续调用它的状态。但是我没有等待这个方法调用,因为使DoWork方法异步会给我一个例外。

但在我的情况下,我当前的电话(请参阅StartCurrentRun方法)后台工作人员最初报告1%,然后它似乎保持空闲状态,并且状态发生变化后报告其余99%。请帮助我如何使BackCrocRun方法与BackCurrentRun方法同步进行后台工作报告。

private void StartCurrentRun(bool obj)
        {
            this.worker = new BackgroundWorker();
            this.worker.WorkerReportsProgress = true;
            this.worker.WorkerSupportsCancellation = true;
            this.worker.DoWork += this.DoWork;
            this.worker.ProgressChanged += this.ProgressChanged;
            this.worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
            IsLiveProgress = true;
            StartTimer();
            this.worker.RunWorkerAsync();
        }

        private void DoWork(object sender, DoWorkEventArgs e)
        {
            CreateEventLogs.WriteToEventLog(string.Format("Run with Assay:{0} Volume{1} has been started", SelectedAssay, SelectedVolume));
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                return;
            }
            int current = 1;
            CurrentCartridgeStatus status = CurrentCartridgeStatus.NotProcessed;
            var instance = ConnectToInstrument.InstrumentConnectionInstance;
            do
            {
                var result = instance.StartCurrentRun(SelectedAssay.display_name, int.Parse(SelectedVolume.Remove(SelectedVolume.Length - 2, 2)));
                //var result = Test(current);
                status = result.Result;
                CurrentStatus = status.ToString();
                CreateEventLogs.WriteToEventLog("Run status - " + CurrentStatus);
                //Thread.Sleep(2000);
                worker.ReportProgress(Math.Min(current, 100));
                current++;
            }
            while (status != CurrentCartridgeStatus.Processed);
            ConnectToInstrument.IsAlreadyExecuted = false;
            if (current < 100)
            {
                worker.ReportProgress(current + (100 - current));
            }
        }    

这是StartCurrentRun方法。它内部调用一些固件逻辑。为了使这更清楚,整个ConnectToInstrument类。

 public class ConnectToInstrument
    {

        private EventProxy _updater;
        private IInstrument _instrument;
        private QpCallBack _cb;
        //private IQEvent @event;
        private QpWrapper _qp;
        private InstrumentTypes _type;
        private CurrentInstrumentStatus InstrumentCurrentStatus = CurrentInstrumentStatus.NotReady;
        private static ManualResetEvent manualResetEvent = new ManualResetEvent(false);
        public static bool IsAlreadyExecuted = false;
        public bool IsConnected { get; set; }

        private static ConnectToInstrument _instrumentConnectionInstance;
        public static ConnectToInstrument InstrumentConnectionInstance
        {
            get
            {
                if (_instrumentConnectionInstance == null)
                {
                    _instrumentConnectionInstance = new ConnectToInstrument();
                }
                return _instrumentConnectionInstance;
            }
        }

        private ConnectToInstrument()
        {
            try
            {
                _cb = new QpCallBack();
                _qp = new QpWrapper();
                //var config = new ConfigManager();
                //var client = new Dna2Client();
                _type = InstrumentTypes.Simulator;
                var factory = new ApiFactory(_cb, _qp, _type);
                _instrument = factory.GetInstrument();
                InitializeQf();
                _updater = new EventProxy();
                _updater.Start(1);
                StartUiProxy().Forget();
            }
            catch (Exception ex)
            {
                //Log to Error Log
            }
        }

        private async Task<object> StartUiProxy()
        {
            while (true)
            {
                try
                {
                    var @event = await _updater.GetEvent();

                    switch ((QpSignals)@event.QSignal)
                    {
                        case QpSignals.INSTRUMENT_STATUS:
                            {
                                var status = @event as UiEvent<InstrumentStatus>;
                                if (status.Value != InstrumentStatus.Ready)
                                {
                                    InstrumentCurrentStatus = CurrentInstrumentStatus.NotConnected;
                                    continue;
                                }
                                else
                                {
                                    InstrumentCurrentStatus = CurrentInstrumentStatus.Ready;
                                    return Task.FromResult<object>(InstrumentStatus.Ready);
                                }
                            }
                        case QpSignals.TRAY_STATUS:
                            {
                                var status = @event as UiEvent<TrayStatus>;
                                if (status.QSignal == 6 && status.Value == TrayStatus.Opened)
                                {
                                    return Task.FromResult<object>(TraySignals.OPEN);
                                }
                                else if (status.QSignal == 6 && status.Value == TrayStatus.Opened)
                                {
                                    return Task.FromResult<object>(TraySignals.CLOSE);
                                }
                                return null;
                            }
                        case QpSignals.PROCESS_CARTRIDGE:
                            {
                                var status = @event as UiEvent<CartridgeStatus>;
                                if (status.Value == CartridgeStatus.Processing)
                                {
                                    return status;
                                }
                                else if (status.Value == CartridgeStatus.Processed)
                                {
                                    return status;
                                }
                                return null;
                            }
                    }
                }
                catch (Exception ex)
                {
                    //Log to Error Log
                }
            }
        }

        private void InitializeQf()
        {
            QF.Instance.Initialize((int)QpSignals.MAX_SIGNAL - 1);
        }
        public async Task<bool> Connect()
        {
            bool status = false;
            string[] ports = new string[40];
            if (_type == InstrumentTypes.Dgx)
            {
                ports = await ComPortInfo.GetAvailablePortNamesForDevice("USB Serial Port");
                if (ports == null || ports.Length == 0)
                {
                    Exception ex = new Exception("No Serial Devices found.");
                    //Log
                    return false;
                }
            }
            try
            {
                string thermPort = _type == InstrumentTypes.Simulator ? string.Empty : ports[0]; //ports[0] should be changed to combobox selected value
                status = _instrument.Connect(ports[0]);
            }
            catch (Exception ex)
            {
                Debug.Write(ex.Message);
            }

            return status;

        }

        public async Task<CurrentInstrumentStatus> GetCurrentInstrumentStatus()
        {
            return await Task.FromResult(InstrumentCurrentStatus);
            //_cb.InstrumentStatusUpdates(InstrumentStatus.Ready);
            //var value = await _updater.GetEvent();
            //var status = value as UiEvent<InstrumentStatus>;
            //if (status.QSignal == 5 && status.Value == InstrumentStatus.Ready)
            //{
            //  return CurrentInstrumentStatus.Ready;
            //}
            //return CurrentInstrumentStatus.Error;
        }

        public async Task<CurrentCartridgeStatus> StartCurrentRun(string Assay, int volume)
        {
            object value;
            UiEvent<CartridgeStatus> status;
            do
            {
                //await Task.Delay(1000);
                //_cb.ProcessCartridge(CartridgeStatus.Processing);
                if (!IsAlreadyExecuted)
                {
                    _instrument.ProcessCartridge();
                }
                IsAlreadyExecuted = true;
                //value = await StartUiProxy();
                value = await _updater.GetEvent();
                status = value as UiEvent<CartridgeStatus>;
            }
            while (status == null);
            try
            {
                //IQEvent value;

                if (status.QSignal == 9 && status.Value == CartridgeStatus.Processing)
                {
                    return CurrentCartridgeStatus.Processing;
                }
                if (status.QSignal == 9 && status.Value == CartridgeStatus.Processed)
                {
                    return CurrentCartridgeStatus.Processed;
                }
            }
            catch (Exception ex)
            {
                //Log it
            }

            return CurrentCartridgeStatus.Unidentified;
        }
    }

这是CurrentCartridgeStatus枚举

  public enum CurrentCartridgeStatus 
    {
        Unidentified = 0,
        NotProcessed = 1,
        Processing = 2,
        Processed = 3
    }

0 个答案:

没有答案