簡體   English   中英

在異步作廢Dowork事件之前觸發RunWorkerCompleted

[英]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();
    }

謝謝你的幫助!

這里的問題與asyncawait BackgroundWorker有點過時了,不支持異步代碼。 因此,當您等待testBLEAsync調用時, callTestBLE方法完成,並且此時您已調用RunWorkerCompleted事件,而實際代碼繼續在后台運行。

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

我同意BackgroundWorkerasync / 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM