继我的BeginInvoke()/ EndInvoke()问题后,在Delegate.BeginInvoke()和使用QueueUserWorkItem()异步调用委托之间的性能/其他任何方面是否存在重大差异?
我能想到的主要事情QueueUserWorkItem
是你必须使用WaitCallback
委托类型,如果你已经有一个实例和一些args ,这看起来很棘手SomeRandomDelegate
.好消息是你可以通过一个闭包解决这个问题:
ThreadPool.QueueUserWorkItem( delegate { someDelegate(arg1, arg2); } );
此模式还可确保您在编译时获得正确的强类型(与将object
状态arg 传递给QueueUserWorkItem
目标方法并将其转换为不同).直接调用方法时也可以使用此模式:
ThreadPool.QueueUserWorkItem( delegate { SomeMethod(arg1, arg2); } );
显然,如果没有EndInvoke
等价物,除非在方法结束时调用方法/引发事件/等等,否则也无法获得返回值...在相关注释中,您需要注意异常处理.
http://blogs.msdn.com/cbrumme/archive/2003/07/14/51495.aspx
说:
"一个令人惊讶的事实是,这也是为什么Delegate.BeginInvoke/EndInvoke与ThreadPool.QueueUserWorkItem(或UnsafeQueueUserWorkItem,如果您了解安全性含义并且希望真正有效)等等技术相比如此之慢..BeginInvoke/EndInvoke的代码路径很快变成了一般远程通道的通用消息处理代码."
该EndInvoke会()有一个有用的,但很少提及行为 - 它重新抛出所有未处理的异常,在原来的线程的上下文中产生的委托,所以你可以将异常处理逻辑到主代码.
此外,如果您的委托有out/ref参数,它们将被添加到EndInvoke()签名中,允许您在方法执行完毕时获取它们.