My Console App uses System.ComponentModel.BackgroundWorker for threading purposes:
System.ComponentModel.BackgroundWorker backgroundWorker = new System.ComponentModel.BackgroundWorker();
backgroundWorker.DoWork += (sender, e) =>
ReportStatus(worker, status, result, e);
backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker.RunWorkerAsync(worker);
As you can see that I am passing “worker” as an argument inside RunWorkerAsync.
What I am trying to achieve is that if there is an exception inside ReportStatus method I need the same “worker” object so that I can perform some operation (Call a service to notify that workers exception)
private void ReportStatus(Worker worker, Status status, WorkResult result,System.ComponentModel.DoWorkEventArgs arg)
{
var proxy = new PreparationServiceProxy(new NetTcpBinding(), new EndpointAddress(PreparationEngineState.ServiceAddress));
try
{
proxy.ReportStatus(worker, status, result);
proxy.Close();
}
catch (Exception)
{
arg.Result = worker;
proxy.Abort();
throw;
}
}
In my exception block (I am not sure if this is the correct way!) I am assigning the worker to the Result so that I can get the same worker back when the RunWorkerCompleted method (backgroundWorker1_RunWorkerCompleted) is executed :
private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
Worker worker = e.Result as Worker; // At this point I get an exception!
}
}
It’s because you re-threw the exception.
BackgroundWorkersees that as an exception unhandled by theDoWorkhandler and re-throws it back on the other thread when you get theResultvalue.If you don’t want it to do that, remove the
throwin your catch in theDoWorkhandler.if you passed the worker object into the
BackgroundWorker, why don’t use just use what you passed in in an exception handler wrapping the call toResultor in the block that testsError? e.g.: