2017-05-24 82 views
0

之前解僱我使用的BLE RSSI水平測試後臺工作。RunWorkerCompleted異步無效的DoWork事件

我的問題是,RunWorkerCompleted事件被立即觸發,路才DoWork的完成它的操作。

大部分DoWork的事件操作是創建一個廣告守望從A藍牙低功耗設備等待信號。 信號電平將從主線程更新,處理結果將在後臺工作人員。

這裏是當我打電話的背景工人:

... 
    worker = new BackgroundWorker(); 
     worker.DoWork += callTestBLE; 
     worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
     worker.RunWorkerAsync(RSSI_Label); 
    } 

事件處理程序:

private async void callTestBLE(object sender, DoWorkEventArgs e) 
    { 
      BluetoothLEAdvertisementWatcher watcher1 ; 
      BluetoothLEAdvertisementFilter advertisementFilter1; 
      int rssiRetries1 = RSSIRETRIES; 
      RssiValue = ""; 

      advertisementFilter1 = new BluetoothLEAdvertisementFilter(); 
      try 
      { 
       advertisementFilter1.Advertisement.LocalName = myUswm.getAdvetrismentName(); 
       checkRSSI = true; 
      } 
      catch (Exception) { checkRSSI = false; return; } 

      watcher1 = new BluetoothLEAdvertisementWatcher(advertisementFilter); 
      watcher1.ScanningMode = BluetoothLEScanningMode.Active; 
      watcher1.Received += OnAdvertisementReceived; 
      // Wait 5 seconds to make sure the device is really out of range 
      watcher1.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000); 
      watcher1.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000); 

      try 
      { 
       watcher1.Start(); 
       await testBLEAsync(); 
       if (myUswm.getConnectionStatus() == DISCONNECTED) 
       { 
        checkNextUUTClick(new object(), new RoutedEventArgs()); return; 
       } 
       for (int i = 0; i < 5; i++) 
       { 
        // if (RssiSamplesNum <= 0 || --rssiRetries < 0) 
        if (RssiSamplesNum <= 0 || --rssiRetries1 < 0) 
        { 
         //serviceList.Clear(); 
         watcher1.Stop(); 
         rssiRetries1 = RSSIRETRIES; 
         RssiSamplesNum1 = numOfAdvertismentSamples; 
         break; 
        } 
        else 
        { 
         ((Label)e.Argument).Content = RssiValue; 
         /*RSSI_Label.Dispatcher.Invoke(new Action(() => 
         { RSSI_Label.Content = RssiValue; }));*/ 
        } 
        Thread.Sleep(2000); 
        }  
      } 
    catch (Exception err) { } 
    } 

    private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     finalizeBleTest(); 
    } 

感謝您的幫助!

+0

你不應該與UI元素進行交互(或稱MessageBox.Show)的背景工人DoWork的線程上,因爲這不是UI線程,並會導致問題。 –

+0

你是對的,代碼在編輯 –

+1

'異步void'應該用於消防*忘記*代碼,因爲沒有手段調用代碼來跟蹤完成。所以我建議你的'DoWork'方法不應該是'async'。使用'BackgroundWorker' *或*使用'async'''' await',但通常情況下,不要試圖合併它們。 –

回答

0

這裏與asyncawait問題。 BackgroundWorker有點過時,不支持異步代碼。所以,當你等待的testBLEAsync通話,callTestBLE方法完成,並在那一刻,你有你的RunWorkerCompleted事件調用,而實際的代碼繼續在後臺運行。

最簡單的解決方案是從代碼中完全刪除async/await,一切都應按預期工作,或者,您可以使用任務和任務延續重寫代碼。

0

我同意BackgroundWorkerasync/await不兼容的其他答案。不過,我不同意最簡單的解決方法是刪除async而不是BackgroundWorker。國際海事組織,優越的解決方案(也導致更簡單的代碼)是刪除BackgroundWorker有利於async;具體地,涉及replace the outdated BackgroundWorker with the superior Task.Run

// `worker` is now `Task`. 
await Task.Run(() => callTestBLE()); 
finalizeBleTest(); 

其中callTestBLE簽名async Task,不async void