QueueUserWorkItem()和BeginInvoke()之间的区别是什么,用于执行不需要返回类型的异步活动

end*_*ian 16 c# multithreading delegates

继我的BeginInvoke()/ EndInvoke()问题后,在Delegate.BeginInvoke()和使用QueueUserWorkItem()异步调用委托之间的性能/其他任何方面是否存在重大差异?

Mar*_*ell 22

我能想到的主要事情QueueUserWorkItem是你必须使用WaitCallback委托类型,如果你已经有一个实例和一些args ,这看起来很棘手SomeRandomDelegate.好消息是你可以通过一个闭包解决这个问题:

ThreadPool.QueueUserWorkItem(
    delegate { someDelegate(arg1, arg2); }
);
Run Code Online (Sandbox Code Playgroud)

此模式还可确保您在编译时获得正确的强类型(与将object状态arg 传递给QueueUserWorkItem目标方法并将其转换为不同).直接调用方法时也可以使用此模式:

ThreadPool.QueueUserWorkItem(
    delegate { SomeMethod(arg1, arg2); }
);
Run Code Online (Sandbox Code Playgroud)

显然,如果没有EndInvoke等价物,除非在方法结束时调用方法/引发事件/等等,否则也无法获得返回值...在相关注释中,您需要注意异常处理.

  • @EnocNRoll - 没有;*lambdas*必须声明正确的参数; 然而,anon-methods可以选择忽略参数.代码是正确的. (4认同)
  • 遇到这个确切的场景是我第一次想到自己,"哇,我喜欢关闭." (3认同)

Kon*_*lev 18

http://blogs.msdn.com/cbrumme/archive/2003/07/14/51495.aspx

说:

"一个令人惊讶的事实是,这也是为什么Delegate.BeginInvoke/EndInvoke与ThreadPool.QueueUserWorkItem(或UnsafeQueueUserWorkItem,如果您了解安全性含义并且希望真正有效)等等技术相比如此之慢..BeginInvoke/EndInvoke的代码路径很快变成了一般远程通道的通用消息处理代码."


Ily*_*yaP 15

该EndInvoke会()有一个有用的,但很少提及行为 - 它重新抛出所有未处理的异常,在原来的线程的上下文中产生的委托,所以你可以将异常处理逻辑到主代码.

此外,如果您的委托有out/ref参数,它们将被添加到EndInvoke()签名中,允许您在方法执行完毕时获取它们.