是否应该始终在AsyncCallback中调用EndInvoke委托?

时间:2009-08-13 04:08:17

标签: .net multithreading

我看过Use AsyncCallback,有这段代码:

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);
  }
}

请注意,在DoSomething2 AsyncCallback中,委托被命令EndInvoke显式杀死。

这真的有必要吗?因为除非代理方法完成运行,否则不会调用AsyncCallback

2 个答案:

答案 0 :(得分:7)

调用EndInvoke()非常重要。如果后台方法生成异常,则调用EndInvoke()将引发该异常,允许主线程处理它。此外,如果后台方法具有返回值,则主线程需要调用EndInvoke()来检索该值。

如果您的后台线程属于以下任何一种情况(生成异常或具有返回值)并且调用EndInvoke(),则后台线程将不会被释放 - 基本上导致资源泄漏。

答案 1 :(得分:3)

有许多讨论都导致了相同的结论 - 如果你不这样做,那就是资源泄漏。

搜索MSDN的警告HereHere
IanG - EndInvoke not optional
CBrumme's blog entry on async operations
关于SO的相关问题 - Do I need to call EndInvoke after a timeout?