Easy Asynchronous Programming

A colleague of mine at work was having some trouble with multithreading this morning and I suggested using asynchronous delegates (a delegate - something you can make do something else, in .NET this can be used as a form of trigger for starting any number of other methods that take and return the same parameters as it uses - that runs its methods in another thread). This got me thinking so I decided to do a quick tutorial for anyone else who hasn't yet encountered this way of doing multithreading!

This is a short sharp example, and can be created in a simple form. Remember not to try to update the form from the method being run by the delegate - if you want to do this you need to run a method that checks if InvokeRequired is true, then runs Invoke(myMethodsOwnName, new object {myFirstParameter, mySecondParameter, andSoOn}) if it is true, or does whatever UI editing is needed if false - so it is calling itself in the context of the user interface.

Anyway, on with the example!

/// <summary>
/// A button on the form
/// </summary>
private void button1_Click(object sender, System.EventArgs e)
{
  delegateInstance = new ExampleDelegate(beginThink);
  d.BeginInvoke(5, new AsyncCallback(finished), null);
}

This is where the program runs, a simple button that can be pressed.  We want to do something CPU intensive and blocking in here but instead we create an instance of a delegate and use the BeginInvoke method, the methods parameters come first (in this case 5) and then the callback method to run, and null for the object state.

/// <summary>
/// An instance of the delegate used to call a method asynchronously
/// </summary>
private ExampleDelegate delegateInstance;
/// <summary>
/// The example delegate
/// </summary>
private delegate string ExampleDelegate(int param);
/// <summary>
/// The example method that would block the user interface
/// </summary>
/// <param name="workOn">Number of seconds to block for</param>
/// <returns>Some string</returns>
private string beginThink(int workOn)
{
  Thread.Sleep(workOn*1000);
  return "Done";
}

This is our ficticious CPU intensive action, in this case we'll just block the thread by seeping for workOn seconds.

/// <summary>
/// The method that is called when work is done
/// </summary>
/// <param name="results">The results of the work</param>
private void finished(IAsyncResult results)
{
  MessageBox.Show(delegateInstance.EndInvoke(results));
}

And this is run when the asynchronous delegate is completed.  EndInvoke automatically return the same type as the delegate, (a string) which makes this nice and easy.

You might also like...

Comments

Simon Soanes

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC. As potential programmers, they are mentally mutilated beyond hope of regeneration.” - E. W. Dijkstra