0

想象以下情况:

  1. 我从第三方服务器的 ui 线程上收到了一个信号。

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

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

  4. 另一个硬件线程将接收硬件数据,然后它本身通过 Invoke 传递到 ui 到 ui 线程中,以根据我得到的硬件数据定期设置一些 ui 元素。

  5. 还不能从数据库中获取数据,但用户界面必须对硬件数据做出反应,硬件数据由第二个异步线程轮询。

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

有时我会遇到异常,后台工作人员很忙,无法同时运行多个任务。

a) 真的需要 ManualResetEvent 对象吗?

b)当后台工作人员不再忙时,检查 isBusy 属性以便仅发出 WaitOne() 就足够了吗?


更新:代码。

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 这样做:

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

1 回答 1

0

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

于 2013-12-03T18:01:28.167 回答