Reputation: 674
I am attempting to make all my code from button clicks, run in a background worker. So I have the following template of code.
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerAsync();
while (backgroundWorker.IsBusy)
{
Application.DoEvents();
}
Just want to know if there is a way to simplify this code, so I am not effectively duplicating the same code block for all my buttons.
EDIT: The typical code I am trying to run is along the lines of:
//Synchronous task
Wait(2000);
//Synchronous task
return taskResult ? "Success" : "Failure"
Upvotes: 2
Views: 987
Reputation: 70701
Without more context, it's impossible to suggest very specific improvements. That said, for sure you can get rid of the while
loop. Just use:
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerAsync();
Note that if you have code you want to execute when the BackgroundWorker
task completes (a possible explanation for why you had that while
loop in the first place), something like this will work (instead of using the while
loop you had before):
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += delegate
{
//code
};
backgroundWorker.RunWorkerCompleted += (sender, e) =>
{
// code to execute when background task is done
};
backgroundWorker.RunWorkerAsync();
In modern C#, BackgroundWorker
is nearly obsolete. The main benefit it provides now is convenient progress reporting, and that is actually easily obtained instead through the use of Progress<T>
.
If you don't need to report progress, factoring your code to use async
/await
is easy:
await Task.Run(() =>
{
//code
});
// code to execute when background task is done
If you do need to report progress, it's only slightly harder:
Progress<int> progress = new Progress<int>();
progress.ProgressChanged += (sender, progressValue) =>
{
// do something with "progressValue" here
};
await Task.Run(() =>
{
//code
// When reporting progress ("progressValue" is some hypothetical
// variable containing the progress value to report...Progress<T>
// is generic so you can customize to do whatever you want)
progress.Report(progressValue);
});
// code to execute when background task is done
Finally, in some cases you might need the task to return a value. In that scenario, it would look more like this:
var result = await Task.Run(() =>
{
//code
// "someValue" would be a variable or expression having the value you
// want to return. It can be of any type.
return someValue;
});
// At this point in execution "result" now has the value returned by the
// background task. Note that in the above example, the method itself
// is anonymous and so you could just set a local variable at the end of the
// task; the value-returning syntax is more useful when you are calling an
// actual method that itself returns a value, and is especially useful when
// you are calling an `async` method that returns a value (i.e. you're not
// even using `Task.Run()` in the `await` statement.
// code to execute when background task is done
You can mix and match the above techniques as needed.
Upvotes: 7