I have written a sample console application to test backgroundworker using one of the examples posted here in Stackoverflow. I have a backgroundworker which start with the main method but its ending in the middle of the operation if I press enter because I have written a console.readkey in the main method. But I want it to wait till the backgroundworker has finished doing the job then exit the application. This is my code.
class Program
{
private static BackgroundWorker worker = new BackgroundWorker();
private event EventHandler BackgroundWorkFinished;
static void Main(string[] args)
{
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.ProgressChanged += worker_ProgressChanged;
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
Console.WriteLine("Starting Application...");
worker.RunWorkerAsync();
Console.ReadKey();
}
static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine(e.ProgressPercentage.ToString());
}
static void worker_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Starting to do some work now...");
int i;
for (i = 1; i < 10; i++)
{
Thread.Sleep(1000);
worker.ReportProgress(Convert.ToInt32((100.0 * i) / 10));
}
e.Result = i;
}
static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine("Value Of i = " + e.Result.ToString());
Console.WriteLine("Done now...");
}
}
Threading. Thread. Sleep(50); return doubleReturn; //doubleReturn is the value that is filled if the BackgroundWorker is complete.
BackgroundWorker, is a component in . NET Framework, that allows executing code as a separate thread and then report progress and completion back to the UI.
BackgroundWorker enables a simple multithreaded architecture for VB.NET programs. This is more reliable, and easier, than trying to handle threads directly. In the Toolbox pane, please double-click on the BackgroundWorker icon. This will add a BackgroundWorker1 instance to the tray at the bottom of the screen.
BackgroundWorker makes the implementation of threads in Windows Forms. Intensive tasks need to be done on another thread so the UI does not freeze. It is necessary to post messages and update the user interface when the task is done.
See the How to wait for a BackgroundWorker to cancel? post for how to communicate between your BackgroundWorker and your main thread.
Basically, you have to use a event that you set at the end of DoWork to signal that DoWork has completed. You then WaitOne() on that event in your main thread.
The main purpose of a Bgw is to interact with the Windows MessageQueue. In other words it is most useful in WinForms and WPF applications.
A Console application is not the right place to use or test a Bgw. You'll get strange results. Print ManagedThreadId at the key points to see what happens.
And some standard advice: Your worker_RunWorkerCompleted()
should check e.Error
. Right now it is the same as having an empty catch{}
block.
Any error from DoWork will now be thrown when you read e.Result
, more complex to handle.
This is what I have done now. But the console.readkey()
is not working. The application is not waiting for the ReadKey()
function.
class Program
{
private static BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
private static AutoResetEvent resetEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.ProgressChanged += worker_ProgressChanged;
worker.WorkerReportsProgress = true;
Console.WriteLine("Starting Application...");
worker.RunWorkerAsync();
resetEvent.WaitOne();
Console.ReadKey();
}
static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine(e.ProgressPercentage.ToString());
}
static void worker_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Starting to do some work now...");
int i;
for (i = 1; i < 10; i++)
{
Thread.Sleep(1000);
worker.ReportProgress(Convert.ToInt32((100.0 * i) / 10));
}
e.Result = i;
resetEvent.Set();
}
static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine("Value Of i = " + e.Result.ToString());
Console.WriteLine("Done now...");
}
}
Fixing Edit: Moved resetEvent.Set()
to inside DoWork rather than in RunWorkerCompleted. The Completed event handler will never get called because the main thread is waiting for the event.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With