title: Calling an async method inside Background worker dosen't report progress paralelly
body: <p>I am calling an async method that returns a Task &lt; CurrentCartridgeStatus> from Background worker. Thing is until the CurrentCartridgeStatus changes its state I want to keep calling it. But I am not awaiting on this method call because making the DoWork method async is giving me an exception. </p>
  
  <p>But in my case with my current call(Please see the StartCurrentRun method) the background worker initially reports 1% then it seems to be staying idle, and after the status changes then it reports the rest 99%. Please help how can I make the Background worker report progress in parallel with StartCurrentRun method.</p>
  
  <pre><code>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 &lt; 100)
              {
                  worker.ReportProgress(current + (100 - current));
              }
          }    
  </code></pre>
  
  <p>Here is the StartCurrentRun method. It internally calls some firmware logic. Just to make this more clear here is the entire ConnectToInstrument Class.</p>
  
  <pre><code> 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&lt;object&gt; StartUiProxy()
          {
              while (true)
              {
                  try
                  {
                      var @event = await _updater.GetEvent();
  
                      switch ((QpSignals)@event.QSignal)
                      {
                          case QpSignals.INSTRUMENT_STATUS:
                              {
                                  var status = @event as UiEvent&lt;InstrumentStatus&gt;;
                                  if (status.Value != InstrumentStatus.Ready)
                                  {
                                      InstrumentCurrentStatus = CurrentInstrumentStatus.NotConnected;
                                      continue;
                                  }
                                  else
                                  {
                                      InstrumentCurrentStatus = CurrentInstrumentStatus.Ready;
                                      return Task.FromResult&lt;object&gt;(InstrumentStatus.Ready);
                                  }
                              }
                          case QpSignals.TRAY_STATUS:
                              {
                                  var status = @event as UiEvent&lt;TrayStatus&gt;;
                                  if (status.QSignal == 6 &amp;&amp; status.Value == TrayStatus.Opened)
                                  {
                                      return Task.FromResult&lt;object&gt;(TraySignals.OPEN);
                                  }
                                  else if (status.QSignal == 6 &amp;&amp; status.Value == TrayStatus.Opened)
                                  {
                                      return Task.FromResult&lt;object&gt;(TraySignals.CLOSE);
                                  }
                                  return null;
                              }
                          case QpSignals.PROCESS_CARTRIDGE:
                              {
                                  var status = @event as UiEvent&lt;CartridgeStatus&gt;;
                                  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&lt;bool&gt; 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&lt;CurrentInstrumentStatus&gt; GetCurrentInstrumentStatus()
          {
              return await Task.FromResult(InstrumentCurrentStatus);
              //_cb.InstrumentStatusUpdates(InstrumentStatus.Ready);
              //var value = await _updater.GetEvent();
              //var status = value as UiEvent&lt;InstrumentStatus&gt;;
              //if (status.QSignal == 5 &amp;&amp; status.Value == InstrumentStatus.Ready)
              //{
              //  return CurrentInstrumentStatus.Ready;
              //}
              //return CurrentInstrumentStatus.Error;
          }
  
          public async Task&lt;CurrentCartridgeStatus&gt; StartCurrentRun(string Assay, int volume)
          {
              object value;
              UiEvent&lt;CartridgeStatus&gt; 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&lt;CartridgeStatus&gt;;
              }
              while (status == null);
              try
              {
                  //IQEvent value;
  
                  if (status.QSignal == 9 &amp;&amp; status.Value == CartridgeStatus.Processing)
                  {
                      return CurrentCartridgeStatus.Processing;
                  }
                  if (status.QSignal == 9 &amp;&amp; status.Value == CartridgeStatus.Processed)
                  {
                      return CurrentCartridgeStatus.Processed;
                  }
              }
              catch (Exception ex)
              {
                  //Log it
              }
  
              return CurrentCartridgeStatus.Unidentified;
          }
      }
  </code></pre>
  
  <p>Here is the CurrentCartridgeStatus enum</p>
  
  <pre><code>  public enum CurrentCartridgeStatus 
      {
          Unidentified = 0,
          NotProcessed = 1,
          Processing = 2,
          Processed = 3
      }
  </code></pre>