C# RunWorkerCompleted在异步void Dowork事件之前激发

C# RunWorkerCompleted在异步void Dowork事件之前激发,c#,backgroundworker,C#,Backgroundworker,我正在使用后台工作程序进行BLE RSSI级别测试 我的问题是RunWorkerCompleted事件在DoWork完成操作之前立即被触发 大多数DoWork事件操作是创建一个广告观察者,并等待来自蓝牙低能设备的信号。 信号电平将从主线程更新,结果的处理将在后台工作程序上进行 下面是我给后台工作人员打电话的时候: ... worker = new BackgroundWorker(); worker.DoWork += callTestBLE; worker

我正在使用后台工作程序进行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();
    }
private async void callTestBLE(对象发送方,DoWorkEventArgs e)
{
蓝牙导线垂直切换器监视器1;
Bluetooth Lead VertizentFilter广告过滤器1;
int rssiRetries1=RSSIRETRIES;
RssiValue=“”;
advertisementFilter1=新的BluetoothLEAdvertisementFilter();
尝试
{
advertisementFilter1.Advertision.LocalName=myUswm.getAdvertisementName();
checkRSSI=true;
}
catch(异常){checkRSSI=false;return;}
watcher1=新的BluetoothLeadVertizentWatcher(广告过滤器);
watcher1.ScanningMode=BluetoothLEScanningMode.Active;
watcher1.已接收+=收到的广告;
//等待5秒钟以确保设备确实超出范围
watcher1.SignalStrengthFilter.OutOfRangeTimeout=TimeSpan.Fromms(5000);
watcher1.SignalStrengthFilter.SamplingInterval=TimeSpan.Fromms(2000);
尝试
{
watcher1.Start();
等待testBLEAsync();
if(myUswm.getConnectionStatus()=已断开)
{
选中下一步单击(新建对象(),新建路由目标());返回;
}
对于(int i=0;i<5;i++)
{

//如果(RssiSamplesNum这里的问题是
async
await
。BackgroundWorker有点过时,不支持异步代码。因此,当您等待
testblesync
调用时,
calltestable
方法完成,此时您调用了
runworkercomplete
事件,而实际的code继续在后台工作


因此,最简单的解决方案是从代码中完全删除
async
/
await
,一切都应该按预期工作,或者,您可以使用任务和任务延续来重写代码。

这里的
async
await
问题。BackgroundWorker有点过时,不支持t异步代码。因此,当您等待
testablesync
调用时,
callTestBLE
方法完成,此时您调用了
RunWorkerCompleted
事件,而实际代码继续在后台工作


因此,最简单的解决方案是从代码中完全删除
async
/
await
,一切都应该按预期工作,或者,您可以使用任务和任务延续来重写代码。

我同意另一个答案,即
BackgroundWorker
async
/
await。但是,我不同意最简单的解决方案是删除
async
而支持
BackgroundWorker
。在我看来,更好的解决方案(也会导致代码更简单)是删除
BackgroundWorker
而支持
async
;具体来说,是:


如果
calltestable
的签名是
async Task
,而不是
async void

我同意另一个答案,即
BackgroundWorker
async
/
wait
不兼容。但是,我不同意最简单的解决方案是删除
async
,而代之以
backgroundworker
.IMO,更好的解决方案(也导致代码更简单)是删除
后台worker
,支持
async
;特别是:


如果
callTestBLE
的签名是
async Task
,而不是
async void

,则不应与UI元素交互(或调用MessageBox.Show)在后台workers DoWork线程上,因为这不是UI线程,会导致问题。你是对的,代码被编辑
async void
应该用于Fire&Forget代码,因为调用代码无法跟踪完成情况。因此我建议你的
DoWork
方法不应该是
async
。使用
BackgroundWorker
或使用
异步
/
等待
,但一般情况下,不要尝试组合它们。不应与UI元素交互(或调用MessageBox.Show)在后台workers DoWork线程上,因为这不是UI线程,会导致问题。你是对的,代码被编辑
async void
应该用于Fire&Forget代码,因为调用代码无法跟踪完成情况。因此我建议你的
DoWork
方法不应该是
async
。使用
BackgroundWorker
或使用
异步
/
等待
,但一般情况下,不要尝试将它们组合在一起。
// `worker` is now `Task`.
await Task.Run(() => callTestBLE());
finalizeBleTest();