C# : Asynchronous Programming Using BeginInvoke and EndInvoke Methods

There are numerous instances in software development where you would find yourself in a need to build responsive apps, an important part of which is the asynchronous way in which you would need to do certain operations like I/O, intensive DB reads or probably making a call to a third party web service hosted somewhere on the cloud.

The .NET framework as a software development platform has come a long way by introducing techniques like delegate based BeginInvoke/EndInvokemultithreading, async/await and the Task & Timer classes.

In this article we will study how to use the BeginInvoke and EndInvoke functions provided through the delegate object that you would use to encapsulate a method. Watch out for other posts on other techniques to make asynchronous calls in .NET.

The below code is a very simple example of a simulated blocking scenario that would pretty often encounter. A simple call to the method – BlockingClass.Sleep() that sleeps the calling thread for the number of seconds passed to it. While this is happening the calling thread is stuck and cannot proceed until this method returns. This practically means it cannot do any other work till just then.

public class BlockingClass
{
    // A method that puts the execution to sleep for the number of seconds specified.
    public string Sleep(int seconds)
    {
        Console.WriteLine("Going to sleep");
        Thread.Sleep(seconds * 1000);
        return "Woke up from sleep.";
    }
}

class Program
{    
    static void Main(string[] args)
    {
        BlockingClass obj = new BlockingClass();
        string returnValue = obj.Sleep(5);
        Console.WriteLine(returnValue);
    }

}

This is just an example of how a blocking scenario would occur. If the duration of the blocking operation is longer, it would mean your calling thread would be stuck for that duration.

That is where the BeginInvoke and EndInvoke operations come in.

You simple define a delegate to encapsulate the Sleep method like so :

public delegate string MethodDelegate(int secondsToSleep);

The signature would need to match your Sleep method.

Once this is done, you can call the BeginInvoke method on the delegate object. This method returns immediately without blocking an IAsyncResult implementation that you can poll to check if the Sleep method completed or not. There are 3 ways using which you can check whether the asynchronous operation completed.

  1. Poll the IAsyncResult.IsCompleted property
  2. Use the IAsyncResult.AsyncWaitHandle property to get WaitHandle and wait on the async operation
  3. Use the EndInvoke method to block the calling thread until the async operation completes.

We will use the third option here. Check out for other posts where I discuss the first and second approach. Here is how you would do it.

The input parameters for the BeginInvoke method are parameters required for the delegate method, an AsyncCallBack delegate object that signifies a callback method you might want to invoke once the async operation is complete and the object that you would pass to this callback method.

Here is the final piece of code :

public class BlockingClass
   {
       // A method that puts the execution to sleep for the number of seconds specified.
       public string Sleep(int seconds)
       {
           Console.WriteLine("Going to sleep");
           Thread.Sleep(seconds * 1000);
           return "Woke up from sleep.";
       }
   }

   class Program
   {
       static void Main(string[] args)
       {
           BlockingClass obj = new BlockingClass();
           MethodDelegate methodDelegate = new MethodDelegate(obj.Sleep);
           IAsyncResult asyncResult = methodDelegate.BeginInvoke(5, null, null);

           //Do some other stuff here for 5 seconds as the BeginInvoke would return immediately anyways.
           Console.WriteLine("Hi there, I will do some more stuff here.");

           //Call the EndInvoke method to wait on the async operation now.
           string returnValue = methodDelegate.EndInvoke(asyncResult);
           Console.WriteLine(returnValue);
           Console.ReadLine();
       }

   }

Here is the output. Notice how the main calling thread proceeds without blocking and prints the message on the console. When we call the EndInvoke method, only then does the calling thread wait on the async operation.

The above way of achieving parallelism is called “asynchronous pattern” or the “asynchronous component pattern”. This is the most basic form of asynchronous programming using the BeginInvoke and EndInvoke methods.

The other two ways are “Event Based Asynchronous Pattern” and the “Task Based Asynchronous Pattern” using the async/await keywords and the Task class.

Leave a Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.