次の状況を想像してください。
サードパーティのサーバーから ui スレッドでシグナルを受け取りました。
RunAsync を使用して BackgroundWorker を開始し、データベースと別の非同期スレッドからデータを取得します。これは、UI スレッドではなく、別のハードウェアをポーリングして信号を受信します。
bg の DoWork イベントハンドラ内で manualresetEvent.Reset() を呼び出します。次に、データ取得メソッドを呼び出し、次に manualresetEvent.Set() を呼び出し、最後に UI スレッドでメソッド METH_UI_1 を呼び出して呼び出します。
他のハードウェア スレッドはハードウェア データを受信し、それ自体が Invoke を介して ui スレッドに渡され、取得したハードウェア データに応じて定期的にいくつかの ui 要素を設定します。
データベースからのデータもまだフェッチできませんが、UI は 2 番目の非同期スレッドによってポーリングされるハードウェア データに反応する必要があります。
METH_UI_1 で manualresetEvent.WaitOne(); を呼び出します。
バックグラウンドワーカーがビジーで、複数のタスクを同時に実行できないという例外が発生することがあります。
a) ManualResetEvent オブジェクトは本当に必要ですか?
b) バックグラウンド ワーカーがビジー状態でなくなったときに、WaitOne() のみを発行するために isBusy プロパティをチェックするだけで十分でしょうか?
更新: コード。
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();
}
}
}
runworkersynch はこれを行います:
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);
}
}