Sunday, June 06, 2010

C# – Asynchronous Programming using BeginInvoke

In C#, delegates automatically get the BeginInvoke and EndInvoke methods defined for them. BeginInvoke is used for running the processes defined by the method and assigned to the delegate on a different thread (asynchronously).

The BeginInvoke method takes a AsyncCallback delegate parameter as a callback method. A common misconception about the BeginInvoke method is that if one does not care about when the method invoked by BeginInvoke completes or its return value, then one can pass in null for this method. THIS IS WRONG! and is partly based on old documentation. If you look at this MSDN document, you can clearly see that the EndInvoke method is not optional but required.

CAUTION   Always call EndInvoke after your asynchronous call completes

Here is more information from IanG: EndInvoke is Required.

So what do you do in Fire-and-Forget scenarios where you dont care about when the method completes or the return value of the method. Simple – use the CallBack parameter to define a call-back method that then calls EndInvoke on the delegate instance. Important: note that I pass in the delegate itself as a parameter to the BeginInvoke method, this allows me to access the delegate via the AsyncState property of the IAsyncResult object.

Sample Code:

Begin Async processing:

//using Action as a shortcut, you could use any delegate that you define instead
Action<int> t = new Action<int>(LongRunningMethod);
IAsyncResult r = t.BeginInvoke(0, new AsyncCallback(CallBack), t);

CallBack method is defined as follows:

private void CallBack(IAsyncResult ar)
      Action<int> t = ar.AsyncState as Action<int>; //AsyncState is set by passing in the delegate to the BeginInvoke’s method.
      t.EndInvoke(ar);//calling EndInvoke - REQUIRED

1 comment:

dragon emperor said...

What happens if we just send null? Memory leak?
Also, is this still valid in C# 5?