Introduction
Running asynchronous tasks can be a nightmare, especially for beginners. In the attached code, you will find a simple AsyncWorker
class that can make your life easier, even if you don't know all the background. I would really like to see your contribution to the provided code, especially to the ReportProgress
function.
Background
Why did I write this helper class? Simply because I didn't like the .NET BackgroundWorker
class and all the issues related with the IsBusy
parameter. Sometimes IsBusy
does not transit from true
to false
even if you successfully end the async task. The backgroundWorker
forces you to use Application.DoEvents
inside a while
loop. That's craziness to me. Maybe there is some other way to use it correctly, but I did not find out how. I tried to follow the same design as BackgroundWorker
to make replacement as simple as possible.
Using the Code
If you look at the BackgroundWorker
documentation, then it should be trivial for you. To initialize the AsyncWorker
, simply define:
AsyncCallback m_asyncWorker;
And somewhere in your code (constructor), initialize it.
this.m_asyncWorker = new AsyncWorker(1);
this.m_asyncWorker.DoWork += new DoWorkEventHandler(m_asyncWorker_DoWork);
Your background task might be anything you like:
void m_asyncWorker_DoWork(object sender, DoWorkEventArgs e) {
Console.WriteLine("Hello world! I was started asynchronously.");
}
And finally to call the background worker, simply type:
if (!this.m_asyncWorker.RunWorkerAsync(true)) {
Console.WriteLine("Worker in use....");
}
By setting RunWorkerAsync
parameter abortIfBusy
to true
, you can skip this event if the previous async call is still running. By setting it to false
, it will wait in a queue and will be fired immediately after IsBusy
switches from true
to false
. This mechanism is very helpful in performance sensitive applications. If you have many "low priority" events that start your AsyncCalls
and in case that the previous async call is still running (IsBusy
), you can decide if another async call should be started or not.
For example: If you are dragging an object on the screen, you do not need to repaint it every time. Just paint it when IsBusy
is false
. If you would like a smoother effect, simply increase the maximumCount
(your thread pool).
At the end, if you need a callback, subscribe yourself to the RunWorkerCompleted
event.
this.m_asyncWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(m_asyncWorker_RunWorkerCompleted);
Points of Interest
Hope this tool will make your life easier now. Please do not ask about locking in JustDoSomething
class. It was part of some other test.
History
- 6 October, 2009 - First release (Igor Alfirevic)