How to use the BackgroundWorker event RunWorkerCompleted
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.
BackgroundWorker RunWorkerCompleted Event
If the BackgroundWorker
was created from the UI thread, then the RunWorkerCompleted
event will also be raised on the UI thread.
If it was created from a background thread, the event will be raised on an undefined background thread (not necessarily the same thread, unless you're using a custom SynchronizationContext
).
Interestingly, this doesn't seem to be all that well-documented on MSDN. The best reference I was able to find was here:
The preferred way to implement multithreading in your application is to use the BackgroundWorker component. The BackgroundWorker component uses an event-driven model for multithreading. The background thread runs your DoWork event handler, and the thread that creates your controls runs your ProgressChanged and RunWorkerCompleted event handlers. You can call your controls from your ProgressChanged and RunWorkerCompleted event handlers.
Backgroundworker's RunWorkerCompleted event is firing even before completing the work
You should add the DoWork
-event handler (and all other event handler, too) before calling RunWorkerAsync()
.
Otherwise, it could happen that RunWorkerAsync
does practically nothing.
Background Object Triggers RunWorkerCompleted event When Process Not Finished
Because you're using an async void
method, the execution of that method ends at the first blocking await
whish means that the work is considered completed for the BackgroundWorker
.
If you're already using asynchronous APIs, you have no need for the BackgroundWorker
. You just need something like this:
private async Task GetMD5HashFromFilesAsync()
{
foreach (string s in lblist.Items)
{
await getMD5HashFromFile2(s).ConfigureAwait(false);
}
}
And, supposing you're calling it from an event handler:
private async void bgwCheckFiles_RunWorkerCompleted(object sender, EventArgs e)
{
await GetMD5HashFromFilesAsync();
MessageBox.Show("Process ended.");
}
RunWorkerCompleted fired before async void Dowork event
The problem here with the async
and await
. BackgroundWorker is a bit outdated and do not support asynchronous code. So when you await for testBLEAsync
call, callTestBLE
method finishes and at that moment you have your RunWorkerCompleted
event called, while actual code continue to work in the background.
So simplest solution is to completely remove async
/await
from your code and everything should work as expected, or, alternatively, you can rewrite your code using tasks and task continuations.
Can I update UI from BackgroundWorker.RunWorkerCompleted
Your code doesn't have a UI thread. Since you don't have a UI thread, and didn't call RunWorkerAsync
from a UI thread (which is required for it to know what UI thread to marshall the event handlers to) it can't call any of the event handlers in a (non-existent) UI thread.
Create a UI application (a winforms or WPF application, for example), make sure to create and run the BGW from a UI thread, and then you'll see that you can manipulate the controls from the various events (other than DoWork
, obviously).
When does the BackGroundWork RunWorkerCompleted event execute?
The Problem is, that a backgroudnworker is another thread that you can't wait for.
The backgroundworker is telling you when it's finished its work.
so your code should look like this
private string hellow="hello";
private void button1_Click(object sender, EventArgs e)
{
bool createAndRunWorkResult = CreateAndRunWork();
}
private bool CreateAndRunWork()
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.RunWorkerAsync();
return true;
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
//Nothing here;
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
hellow="aloha";
//Do something that need wait RunBackGroundWorkerCompleted execute here.
//MessageBox.Show(hellow);
}
I recommend reading this: http://msdn.microsoft.com/en-us/library/ms173178%28v=vs.120%29.aspx
about threading
Related Topics
How to Unserialize PHP Serialized Array/Variable/Class and Return Suitable Object in C#
How to Write an Async Method with Out Parameter
How to Display a Popup from a Webbrowser in Another Window I Created
Creating a Comma Separated List from Ilist<String> or Ienumerable<String>
How to Decode a Base64 Encoded String
Open File with Associated Application
Does C++11 Have C#-Style Properties
Is Ruby's Code Block Same as C#'s Lambda Expression
Replace Multiple Characters in a C# String
How to Fix a Opacity Bug with Drawtobitmap on Webbrowser Control
Order of Event Handler Execution