想象以下情况:
我从第三方服务器的 ui 线程上收到了一个信号。
我用 RunAsync 启动一个 BackgroundWorker 从数据库和另一个异步线程中获取数据,该线程将轮询另一个硬件并接收信号,也不在 ui 线程中
在 bg 的 DoWork 事件处理程序中,我调用 manualresetEvent.Reset()。然后我调用数据获取方法,然后调用manualresetEvent.Set(),最后通过调用它来调用ui线程上的方法METH_UI_1。
另一个硬件线程将接收硬件数据,然后它本身通过 Invoke 传递到 ui 到 ui 线程中,以根据我得到的硬件数据定期设置一些 ui 元素。
还不能从数据库中获取数据,但用户界面必须对硬件数据做出反应,硬件数据由第二个异步线程轮询。
在 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);
}
}