Click here to Skip to main content
15,890,527 members
Articles / Programming Languages / C#

A Simple Way To Use Asynchronous Call in Your Multithreaded Application

Rate me:
Please Sign up or sign in to vote.
2.75/5 (8 votes)
13 Apr 2017CPOL2 min read 33.4K   604   30   6
A simple way to use asynchronous calls

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:

C#
AsyncCallback m_asyncWorker;		 

And somewhere in your code (constructor), initialize it.

C#
//By setting the maximumCount, we can simulate the simple ThreadPool.
//The maximumCount parameter tells you how many concurrent threads may be
//started simultaneously. Others will wait or be rejected if abortIfBusyParameter
//is set to true.
this.m_asyncWorker = new AsyncWorker(1);

//assign a background task
this.m_asyncWorker.DoWork += new DoWorkEventHandler(m_asyncWorker_DoWork);

Your background task might be anything you like:

C#
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:

C#
//because abortIfBusyParameter is set to true, RunWorkerAsync will
//return false (abort the call) if the previous call is still running. 
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.

C#
//assign to a RunWorkerCompleted. It is your callback 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)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Slovenia Slovenia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 1 Pin
Vyacheslav Trubarov13-Oct-09 1:54
Vyacheslav Trubarov13-Oct-09 1:54 
GeneralRe: My vote of 1 Pin
gico13-Oct-09 8:07
gico13-Oct-09 8:07 
Question"Sometimes IsBusy does not transit from true to false even if you successfully end the async task." Pin
f r i s c h12-Oct-09 2:16
f r i s c h12-Oct-09 2:16 
AnswerRe: "Sometimes IsBusy does not transit from true to false even if you successfully end the async task." Pin
gico13-Oct-09 3:59
gico13-Oct-09 3:59 
GeneralRe: "Sometimes IsBusy does not transit from true to false even if you successfully end the async task." Pin
f r i s c h13-Oct-09 4:13
f r i s c h13-Oct-09 4:13 
GeneralRe: "Sometimes IsBusy does not transit from true to false even if you successfully end the async task." Pin
gico13-Oct-09 7:21
gico13-Oct-09 7:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.