问题
All,I already knew the basic usage the BackgroundWorker
to handle multiple thread case in the WinForm . And the code structure looks like below.
In the main thread of application. just start the BackgroundWork.
if (backgroundWorker1.IsBusy != true)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
}
Then it would fire the DoWork
event . So we can do something in there.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
......
// report progress.
worker.ReportProgress(iProgress);
....
}
Then we just need to handle the ProgressChanged
event to show the BackgroundWorker progress.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//show progress.
resultLabel.Text = (e.ProgressPercentage.ToString() + "%");
}
After DoWork
finished or some exception happened. the event RunWorkerCompleted
would be fired.
Here comes my questions for this events handle. please help to review them. thanks.
I noticed there is property named 'Result' in the RunWorkerCompletedEventArgs e
, What does it use for? How can I use it ?
Is there any possibility to receive my custom exception message instead the e.error
? If there is, How to make it ?
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
resultLabel.Text = "Canceled!";
}
else if (e.Error != null)
{
resultLabel.Text = "Error: " + e.Error.Message;
}
else
{
resultLabel.Text = e.Result.ToString();
}
}
回答1:
The Result
property in RunWorkerCompletedEventArgs
is the value you have assigned to the Result property of DoWorkEventHandler
in DoWork()
.
You can assign anything you like to this, so you could return an integer, a string, an object/composite type, etc.
If an exception is thrown in DoWork()
then you can access the exception in the Error
property of RunWorkerCompletedEventArgs
. In this situation, accessing the Result property will cause an TargetInvocationException
to be thrown.
回答2:
public class MyWorkerClass
{
private string _errorMessage = "";
public string ErrorMessage { get { return _errorMessage; } set { _errorMessage = value; }}
public void RunStuff(object sender, DoWorkEventArgs e)
{
//... put some code here and fill ErrorMessage whenever you want
}
}
then the class where you use it
public class MyClassUsingWorker
{
// have reference to the class where the worker will be running
private MyWorkerClass mwc = null;
// run the worker
public void RunMyWorker()
{
mwc = new MyWorkerClass();
BackgroundWorker backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.DoWork += new DoWorkEventHandler(mwc.RunStuff);
backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string strSpecialMessage = mwc.ErrorMessage;
if (e.Cancelled == true)
{
resultLabel.Text = "Canceled!";
}
else if (e.Error != null)
{
resultLabel.Text = "Error: " + e.Error.Message;
}
else
{
resultLabel.Text = e.Result.ToString();
}
}
}
回答3:
You can use the Result property to store any results from the DoWork and access it from Completed event. But if the background worker process got cancelled or an exception raised, the result won't be accessible. You will find more details here.
来源:https://stackoverflow.com/questions/19723742/how-to-use-the-backgroundworker-event-runworkercompleted