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

.net 是否应该始终在AsyncCallback中调用EndInvoke委托?,.net,multithreading,.net,Multithreading,我读了,有一段代码: 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

我读了,有一段代码:

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
中,这是一个
异步回调
,委托被命令
EndInvoke
显式终止

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

调用EndInvoke()非常重要。如果后台方法生成异常,那么调用EndInvoke()将引发该异常,从而允许主线程处理该异常。另外,如果后台方法有一个返回值,那么主线程需要调用EndInvoke()来检索该值

如果您的后台线程属于这两种情况之一(生成异常或具有返回值),并且您没有调用EndInvoke(),那么后台线程将不会被释放,这将导致资源泄漏。

是。

有一系列的讨论都得出了相同的结论——如果你不这样做,那就是资源泄漏

搜索MSDN的注意事项和



关于SO-

btw的一个相关问题:Delegate.BeginInvoke与使用线程池相比效率相对较低,这里有一个包含一些信息的页面:@Yoooder,这让我感到惊讶,因为BeginInvoke也使用线程池。在这里阅读:这也让我感到惊讶,实际上有点震惊和失望(这是我对异步工作的首选模式),但这似乎是事实。我们已经在一个自定义实现中复制了该模式,该实现使用了线程池,而没有远程处理功能——模式的所有好处,没有任何开销……我还应该说“与直接使用线程池相比”。效率低下的原因是远程处理组件/层透明地发挥作用;正如@tuinstoel指出的,BeginInvoke()实际上仍然使用ThreadPool,将接口引用转换回实现类型是一种气味。。这似乎不是解决问题的办法——也许事后诸葛亮总是20-20