views:

317

answers:

2

I read the Use AsyncCallback, there is this code snippet:

using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
class MainClass
{
  delegate int MyDelegate(string s);

  static void Main(string[] args)
  {
    MyDelegate X = new MyDelegate(DoSomething);
    AsyncCallback cb = new AsyncCallback(DoSomething2);
    IAsyncResult ar = X.BeginInvoke("Hello", cb, null);

    Console.WriteLine("Press any key to continue");
    Console.ReadLine();
  }
  static int DoSomething(string s)
  {
    Console.WriteLine("doooooooooooooooo");
    return 0;
  }

  static void DoSomething2(IAsyncResult ar)
  {
    MyDelegate X = (MyDelegate)((AsyncResult)ar).AsyncDelegate;
    X.EndInvoke(ar);
  }
}

Note that in DoSomething2, which is an AsyncCallback, the delegate is explicitly killed by the command EndInvoke.

Is this really necessary? Because AsyncCallback won't get called unless and until the delegate method is finished running.

+2  A: 

Calling EndInvoke() is very important. If the background method generates an exception then calling EndInvoke() will raise that Exception, allowing your main thread to handle it. Also, if the background method has a return value then the main thread needs to call EndInvoke() to retrieve that value.

If your background thread falls under either of these situations (generates an exception or has a return value) and you don't call EndInvoke() then the background thread won't be freed--essentially resulting in a resource leak.

STW
+1  A: 

Yes.

There are a bunch of discussions all leading to the same conclusion - It's a resource leak if you don't.

search for MSDN's Caution Here and Here
IanG - EndInvoke not optional
CBrumme's blog entry on async operations
A related question on SO - Do I need to call EndInvoke after a timeout?

Gishu