Imagine following situation:
I got a signal on the ui thread from a third party server.
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
Inside the bg's DoWork eventhandler I call 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.
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.
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.
In METH_UI_1 I call 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 ?
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 ?
UPDATE: CODE.
MainForm.cs (event handler of third party hw-vendor, component, handled in ui thread)
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:
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:
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. If its at the very end , I would hook into the backgroundworker workcompleted event and set it in there.