Library code snippets
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.
Related articles
Related discussion
-
Help me how to dynamic create row column of TableLayoutpanel at run time ??????
by anatha1 (0 replies)
-
Very Urgent regarding deleting the images from a folder
by rameshbandi (2 replies)
-
How to Export Datagridview contents to Excel
by BarbaMariolino (8 replies)
-
Help accessing sound card
by daz4904 (0 replies)
-
How to Write a GPS Application
by stoyac (19 replies)
Related podcasts
-
Object-Oriented Programming in Ruby
In this episode, I talk with Scott Bellware about object-oriented programming in Ruby, and Ruby's object model. This is taken from a private conversation, and the audio quality suffers at times. Much thanks to Scott for allowing this to be released.This episode of the Alt.NET Podcast is bro...
I should have first read MSDN.
Blame on me.
Thank you for a great tip!
Works very well here.
Shamil
But this code doesn't compile:
/// <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);
}
it should be:
/// <summary>
/// A button on the form
/// </summary>
private void button1_Click(object sender, System.EventArgs e)
{
delegateInstance = new ExampleDelegate(beginThink);
delegateInstance.BeginInvoke(5, new AsyncCallback(finished), null);
}
Question: I'm not sure I quite understand this sentence from your post:
"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. "
I did adapt your sample for my form to start asynchronously a "CPU hog" thread - it works OK, my form doesn't block and I can set this form's title and the values of its controls by using direct delegate call from asynchronously running thread. Is that OK? Or it may result in some problems and this is what you are talking about when mentioning "InvokeRequired" etc...
Thanks you,
Shamil
This thread is for discussions of Easy Asynchronous Programming.