带有BackgroundWorker的ManualResetEvent:WaitOne()时当前线程正忙吗?

时间:2013-12-03 16:47:52

标签: c# .net multithreading backgroundworker manualresetevent

想象一下以下情况:

  1. 我从第三方服务器上获得了ui线程的信号。

  2. 我使用RunAsync启动BackgroundWorker以从数据库和另一个异步线程获取数据,该异步线程将进行轮询 另一个硬件和接收信号,也不在ui线程

  3. 在bg的DoWork事件处理程序中,我调用了manualresetEvent.Reset()。然后我调用data-fetching方法,然后调用manualresetEvent.Set(),最后通过调用它来调用ui线程上的方法METH_UI_1。

  4. 其他硬件线程必须接收硬件数据,然后将其本身通过Invoke传递给ui线程,根据我得到的硬件数据定期设置一些ui元素。

  5. 也无法获取数据库中的数据,但ui必须对硬件数据作出反应,该数据由第二个异步线程轮询。

  6. 在METH_UI_1中,我调用了manualresetEvent.WaitOne();

  7. 有时我得到异常,后台工作人员很忙,不能同时运行多个任务。

    a)是否真的需要一个ManualResetEvent对象?

    b)当后台工作者不再忙时,检查isBusy属性以便仅发出WaitOne()是否足够?


    更新:代码。

    MainForm.cs(第三方hw-vendor的事件处理程序,组件,在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这样做:

    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;
            }            
        }
    

    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);
            }
        }
    

1 个答案:

答案 0 :(得分:0)

尽管很少见,但在dowork方法块中设置manualresetEvent时可能无法完成BackgrounWorker。如果它在最后,我会挂钩到backgroundworker workcompleted事件并将其设置在那里。