Resources / C# / Delegates And Multihreading Using Asynchronous Delegates /
Select CategoryEnter KeywordsSearch
Search {27416} Articles (Last Index: 11/03/2010 23:57:04)
Delegates And Multihreading Using Asynchronous Delegates
Subscribe Bookmark and Share

 

Delegates and Multithreading Using Asynchronous Delegates

 

As we will see delegates can be used to run multiple threads.  The following examples go through 5 different scenarios from basic synchronous delegates right the way through to Asynchronous delegates with callbacks.

 

In this example project there is one class.

 

class AsynchronousProgram

 

In this class we have 7 methods.  5 delegate example methods.   

 

static void SynchronousDelegate()

 

static void ASynchronousDelegate1()

 

static void ASynchronousDelegate2()

 

static void ASynchronousCallbackDelegate1()

 

static void ASynchronousCallbackDelegate2()

 

2 methods to be run as delegates

 

static int Add(int x, int y)

 

static void AddComplete(IAsyncResult iftAR)

 

We have our main method which will run each of the delegate example methods as we uncomment them.

 

And a delegate definition called MyOperation in our namespace BUT outside of the class as below

 

public delegate int MyOperation(int x, int y);

  

 class AsynchronousProgram

    {

        static void Main(string[] args)

        {

            SynchronousDelegate();

            //ASynchronousDelegate1();

            //ASynchronousDelegate2();

            //ASynchronousCallbackDelegate1();

            //ASynchronousCallbackDelegate2();

        }

 

The method that will be run here will be the SynchronousDelegate but of course we will run the others by uncommenting them as we run through this article.
Synchronous Delegates

 

First let’s have a very quick review of synchronous delegates so we can understand by what we mean by the term synchronous.

 

Here is our first example delegate method

 

static void SynchronousDelegate()    

        {

Console.WriteLine("************A Quick Synchronous Delegate Review************");

 

              //Print out the ID of the executing Thread.

Console.WriteLine("Main() invoked on Thread {0}.", Thread.CurrentThread.GetHashCode());

 

 

              //Invoke Add() in a Synchronous manner.

 

              MyOperation b = new MyOperation(Add);

              int answer = b(10, 10);

 

 

              // Now we have to wait These lines will not

              // execute until the Add() method has completed

              // because this happens synchronously one method after

              //the other

              Console.WriteLine("Doing more work in Main()!");

              Console.WriteLine("10 + 10 is {0}", answer);

              Console.ReadLine();

          }

 

Followed by our add method

 

    static int Add(int x, int y)

        {

            //Print out the ID of the executing Thread.

            Console.WriteLine("Add() invoked on Thread {0}.", Thread.CurrentThread.GetHashCode());

 

            //Pause to simulate a lengthy operation

            Thread.Sleep(5000);

            return x + y;

        }

 

You’ll notice that we have the following using statement

 

using System.Threading;

 

Because in both methods we use the following line to identify and print out the thread we are working with

 

Thread.CurrentThread.GetHashCode());

 

And the line

 

Thread.Sleep(5000);

In our add method to make the method wait for a while.

 

The add method is put into our new delegate object b which is of the type MyOperation.

 

And the method invoked by calling b and assigning the return to answer.  As our method is invoked synchronously the line from the method is printed first as we have to wait for the add method to finish BEFORE we get the next few lines printed from the main method.

 

So when the routine is run we get the following output with a sleight pause after the line from the Add method.  Notice also that the identity of the thread is 1 from both methods.  That is because they are working synchronously ‘One after the other’ on the SAME thread.  Work is blocked until the preceding work is finished.

 

SynchronousDelegate output

  

Asynchronous Delegates Part 2

 

Looking at the following piece of code you will see it does pretty much the same as the previous example only this time we have added a while loop

static void ASynchronousDelegate2()

    {

        Console.WriteLine("************Second ASynchronous Delegate Invocation************");

 

        //Print out the ID of the executing Thread.

        Console.WriteLine("Main() invoked on Thread {0}.", Thread.CurrentThread.GetHashCode());

 

 

        //Invoke Add() on a Secondary Thread.

 

        MyOperation b = new MyOperation(Add);

        IAsyncResult iftAR = b.BeginInvoke(10, 10, null, null);

 

// This message will keep printing until the Add() method is finished

        while (!iftAR.IsCompleted)

        {

            Console.WriteLine("Doing more work in Main()!");

        }

        //Now we know the Add() method is complete

        int answer = b.EndInvoke(iftAR);

        Console.WriteLine("10 + 10 is {0}", answer);

        Console.ReadLine();

    }

This while loop checks the value of our IAsynchResult object iftAR’s property IsCompleted and no prizes for guessing……. This is a Boolean value that tells us if the method has finished by returning true when this is the case.

 

This means the loop will continue until the method has returned so we can then go and collect the result.  Meanwhile until that is the caseDoing more work in Main()!");’will be printed to the consol as shown in the output below.

 

Asynchronous Delegates2 Example Output

 

Asynchronous Callback Delegate Part 1

 

So now we have seen asynchronous delegates in action and understood how the work and what they do lets take a step further and look at asynchronous delegates that can make a callback rather than wait to be asked if it is ready.

 

Let’s look at the following code

 

static void ASynchronousCallbackDelegate1()

    {

        Console.WriteLine("************First ASynchronous Callback Delegate Example************");

 

        //Print out the ID of the executing Thread.

        Console.WriteLine("Main() invoked on Thread {0}.", Thread.CurrentThread.GetHashCode());

       

 

        MyOperation b = new MyOperation(Add);

        IAsyncResult iftAR = b.BeginInvoke(10, 10, new AsyncCallback(AddComplete),null);

 

        // Other work performed here

          

        //Console.WriteLine("10 + 10 is {0}", answer);

        Console.ReadLine();

    }

 

This is the code that is going to call the following method in an asynchronous manner.

 

static void AddComplete(IAsyncResult iftAR)

        {

            //Part 1

Console.WriteLine("AddComplete() invoked on Thread {0}.", Thread.CurrentThread.GetHashCode());

            Console.WriteLine("Your Addition is complete");

            // Part 2 Now get the result

            AsyncResult ar = (AsyncResult)iftAR;

            MyOperation b = (MyOperation)ar.AsyncDelegate;

            Console.WriteLine("10 + 10 is {0}", b.EndInvoke(iftAR));

        //Part 3Retrieve the info part object and cast it to string

            string msg = (string)iftAR.AsyncState;

            Console.WriteLine(msg);

 

 

        }

 

This time when we call the BeginInvoke method on our delegate b we pass across the addComplete method as parameter to a new AsynchCallback object.  This is now acting as a delegate and as any delegate can only take a method that matches its own pattern which in this case is one that takes a type IAsynchResult as a sole parameter and has no return.

 

Now we don’t have to poll the delegate to check if it is finished, instead it will run the method we have passed to the BeginInvoke method which in this case is addComplete.  You can see this when you run the program, the addComplete method is invoked on the same thread as the add method.

 

You may also notice that the EndInvoke method is now not called in Main  and it is not catching the IAsynchResult. The reason for this is that the delegate is not visible in the method addComplete.  However the elegant thing about this is that the object being passed in is actually an object of type AsynchResult.  From this we can get hold of the actual delegate created elsewhere in Main in this case with the following line

MyOperation b = (MyOperation)ar.AsyncDelegate;

 

Now we have a reference to the original delegate and we can call the EndInvoke method here giving us the result of add

 

ASynchronousCallbackDelegate1 Example

Asynchronous Callback Delegate Part 2

 

And for our final piece of code an example of using an object passed into the

The BeginInvoke method of the delegate.

 

Here’s the method:

 

static void ASynchronousCallbackDelegate2()

    {

 Console.WriteLine("************Second ASynchronous Callback Delegate Example************");

 

        //Print out the ID of the executing Thread.

        Console.WriteLine("Main() invoked on Thread {0}.", Thread.CurrentThread.GetHashCode());

 

 

        MyOperation b = new MyOperation(Add);

IAsyncResult iftAR = b.BeginInvoke(10, 10, new AsyncCallback(AddComplete), "Thanks for adding these numbers");

 

        // Other work performed here

 

        //Console.WriteLine("10 + 10 is {0}", answer);

        Console.ReadLine();

    }

 

Only difference to the previous piece of code is this line:

 

IAsyncResult iftAR = b.BeginInvoke(10, 10, new AsyncCallback(AddComplete), "Thanks for adding these numbers");

 

And specifically this

 

We are now passing n a String object that we can use later in the returning function.  This could be any object.

 

And here is where we use it:

 

        static void AddComplete(IAsyncResult iftAR)

        {

            //Part 1

            Console.WriteLine("AddComplete() invoked on Thread {0}.", Thread.CurrentThread.GetHashCode());

            Console.WriteLine("Your Addition is complete");

            // Part 2 Now get the result

            AsyncResult ar = (AsyncResult)iftAR;

            MyOperation b = (MyOperation)ar.AsyncDelegate;

            Console.WriteLine("10 + 10 is {0}", b.EndInvoke(iftAR));

            //Part 3Retrieve the info part object and cast it to string

            string msg = (string)iftAR.AsyncState;

            Console.WriteLine(msg);

 

 

        }

 

 

 

 And that is what gives us the last line in our program output.

 

ASynchronousCallbackDelegate2 Example

 

 

 

So there you go…… Hopefully this article has helped you understand the differences between synchronous and asynchronous delegates and given you a start on how to use asynchronous delegates and asynchronous delegates with call backs.

 

Just uncomment the line in main to run the specific method you want to try out.

 

Have fun!!!!!!!!!!

 

Written By LHTP Limited [http://www.learnhowtoprogram.com/]

Keywords:
Delegates And Multihreading Using Asynchronous Delegates

Return to previous page

Attachments
FileExtensionSize (bytes)Modified Date
152.zip.zip19146906/04/2009 12:05:13
Send to a friend
Add Your Comments

You are not currently logged on.
You must be a registered member to comment on our resource pages.

It is free to register. You can register here Registration Form

Login / Register
Description

Resources

C# | Visual Basic | ASP.Net | SQL | CSS | XML | Java Script | AJAX | UML | Python | Perl | PHP | Oracle | MySql | Sybase | LINQ | Struts | Sharepoint | J2EE | Java | Mobile | .NET | Ruby | DB2 | DirectX | Silverlight | C++ | 

Courses

VB.Net | 

Company

Terms of Service | Advertising | Privacy Policy | Content Provider Agreement | Open Licence | 

Site Map (Visual) | Site Map

Copyright © 2008 Learn How To Program. All rights reserved.