[英]RunWorkerCompleted fired before async void Dowork event
我正在使用背景工進行BLE RSSI級別測試。
我的問題是RunWorkerCompleted事件在DoWork完成操作之前立即被觸發。
DoWork事件的大多數操作是創建廣告觀察程序,並等待來自低功耗藍牙設備的信號。 信號電平將從主線程進行更新,結果的處理將在后台工作程序中進行。
這是我給背景工作者打電話的時候:
...
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();
}
謝謝你的幫助!
這里的問題與async
和await
。 BackgroundWorker有點過時了,不支持異步代碼。 因此,當您等待testBLEAsync
調用時, callTestBLE
方法完成,並且此時您已調用RunWorkerCompleted
事件,而實際代碼繼續在后台運行。
因此,最簡單的解決方案是從代碼中完全刪除async
/ await
,一切都將按預期工作,或者,您也可以使用任務和任務延續來重寫代碼。
我同意BackgroundWorker
與async
/ await
不兼容的另一個答案。 但是,我不同意最簡單的解決方案是刪除async
,而使用BackgroundWorker
。 IMO的高級解決方案(也導致更簡單的代碼)是刪除BackgroundWorker
,而支持async
; 具體來說, 用高級Task.Run
替換過時的BackgroundWorker
:
// `worker` is now `Task`.
await Task.Run(() => callTestBLE());
finalizeBleTest();
其中callTestBLE
的簽名是async Task
,而不是async void
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.