简体   繁体   English

使用BackgroundWorker的ManualResetEvent:WaitOne()时当前线程忙吗?

[英]ManualResetEvent with a BackgroundWorker : Current thread is busy while WaitOne()?

Imagine following situation: 想象以下情况:

  1. I got a signal on the ui thread from a third party server. 我从第三方服务器收到有关ui线程的信号。

  2. I start a BackgroundWorker with RunAsync to fetch data from a database and another async thread, which shall poll another hardware and receive signals, also not in ui thread 我用RunAsync启动BackgroundWorker来从数据库和另一个异步线程中获取数据,该线程将轮询另一个硬件并接收信号,同样不在ui线程中

  3. Inside the bg's DoWork eventhandler I call manualresetEvent.Reset(). 在bg的DoWork事件处理程序中,我称为manualresetEvent.Reset()。 Then I call the data-fetching method, and then I call manualresetEvent.Set() and in the end I call the method METH_UI_1 on the ui thread by invoking it. 然后,我调用数据获取方法,然后调用manualresetEvent.Set(),最后通过调用它在ui线程上调用方法METH_UI_1。

  4. The other hardware thread shall receive hardware-data, which then itself is passed via Invoke to the ui into the ui thread to set some ui-elements periodically depending on the hardware-data I get. 另一个硬件线程将接收硬件数据,然后将其本身通过Invoke传递到ui到ui线程中,以根据我得到的硬件数据定期设置一些ui元素。

  5. The data from database can also not be fetched yet, but the ui must react to the hardware-data, which is polled by the second async thread. 还无法从数据库中获取数据,但是ui必须对硬件数据作出反应,该数据由第二个异步线程轮询。

  6. In METH_UI_1 I call manualresetEvent.WaitOne(); 在METH_UI_1中,我称为manualresetEvent.WaitOne();。

Some times I get the exception, that the background worker is busy and cannot run multiple tasks concurrently. 有时我会得到一个例外,后台工作人员很忙,无法同时运行多个任务。

a) Is there really a need for a ManualResetEvent object ? a)确实需要一个ManualResetEvent对象吗?

b) Would it be enough, to check for the isBusy property in order to issue WaitOne() only, when the background worker is no more busy ? b)仅在后台工作人员不再忙时检查isBusy属性以便仅发出WaitOne()足够了吗?


UPDATE: CODE. 更新:CODE。

MainForm.cs (event handler of third party hw-vendor, component, handled in ui thread) MainForm.cs(第三方硬件供应商的事件处理程序,组件,在ui线程中处理)

 private void thrdptyPlcGotData(object sender, thrdptyPlcGotDataEventArgs e)
    {
        string strError = string.Empty;
        bool blNotReadyYet = false;            

        try
        {
            ThrdPtyPlcIfs.DataSetthrdptyPlc ds;

                ds = new ThrdPtyPlcIfs.Dataset();
                e.FillDataToTDataSet(ds);
               ThrdPtyPlcIfs.Statics.SaveDataSet(ds, CLStatics.FileName);


                               if (this.ValidateDsDetail(ds))
                                {
                                    // begin async work..... ask db, continue asking scale-> inside got weight of scale the rest is handled ( using or trashing db data )
                                    this.ExtractDataOfDataSet(ds);
                                    this.bgWorkerStart_Get_Data.RunWorkerAsync();                                        

                                    _oAsyncScaleManager.StartThread();
                                 }
         }
}

runworkerasynch does this: runworkerasynch这样做:

private void bgWorkerStart_Get_Data_RFC_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {

            _blnStart_Get_Data_RFC = this.StartGetData_RFC(null);
        }
        catch (Exception ex)
        {
            LogExcep(ex);
            _blnStart_Get_Data_RFC = false;
        }            
    }

WorkCompleted EventHandler of the BackGroundWorker: BackGroundWorker的WorkCompleted EventHandler:

 private void bgWorkerStart_Get_Data_RFC_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {            
        try
        {  
            if (InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate()
                {
                    this.ApplyDbDataToUi();
                }
                            );
            }
            else
            {
                this.ApplyDbDataToUi();
            }

        }
        catch (Exception ex)
        {
            LogAndShowExep(ex);
        }
    }

As rare as it might be , its possible the BackgrounWorker isn't finished when you set manualresetEvent inside the dowork method block. 极少见的是,当您在dowork方法块内设置manualresetEvent时,BackgrounWorker可能没有完成。 If its at the very end , I would hook into the backgroundworker workcompleted event and set it in there. 如果它在最后,我将挂接到backgroundworker workcompleted事件并将其设置在那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM