当前位置: 首页 > 编程语言 > C#

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

时间:2023-04-10 17:30:21 C#

QueueUserWorkItem()和BeginInvoke()有什么区别返回类型跟进我的BeginInvoke()/EndInvoke()问题,Delegate.BeginInvoke()和使用QueueUserWorkItem()异步调用委托之间在性能/其他方面是否有任何重大差异?http://blogs.msdn.com/cbrumme/archive/2003/07/14/51495.aspx说:“一个令人惊讶的事实是,这也是Delegate.BeginInvoke/EndInvoke与ThreadPool.QueueUserWorkItem(或UnsafeQueueUserWorkItem,如果你了解安全隐患并想真正工作)等等技术相比之下太慢了..BeginInvoke/EndInvoke的代码路径很快变成了通用远程通道的通用消息处理代码。”QueueUserWorkItem我能想到的主要是你必须使用WaitCallback委托类型,如果你已经有一个SomeRandomDelegate实例和一些参数,这看起来很棘手。好消息是你可以用闭包来解决这个问题:ThreadPool.QueueUserWorkItem(delegate{someDelegate(arg1,arg2);});此模式还确保您在编译时获得正确的强类型(与传递对象状态arg给QueueUserWorkItem并将其强制转换为目标方法不同)。直接调用方法时也可以使用此模式:ThreadPool.QueueUserWorkItem(delegate{SomeMethod(arg1,arg2);});显然,如果没有EndInvoke等价物,除非在方法结束时调用/引发事件/等,否则也无法获取返回值......在相关说明中,您需要处理异常处理。EndInvoke()有一个有用但很少提及的行为-它会重新抛出委托在原始线程的上下文中生成的所有未处理的异常,因此您可以将异常处理逻辑移到主代码中。此外,如果您的委托有out/ref参数,它们将被添加到EndInvoke()签名中,允许您在方法完成执行时获取它们。如果调用ThreadPool.QueueUserWorkItem,工作项中抛出的异常将不会在后台线程中处理(除非您明确捕获它们)。在.Net2及更高版本中,这将终止您的AppDomain。如果调用了delegate.BeginInvoke(),异常将排队等候在调用EndInvoke()时重新抛出。如果您从不调用EndInvoke(),则异常基本上是“泄漏”内存(就像异步操作未释放的任何其他状态一样)。应该没有太大的区别,我也认为为委托生成的BeginInvoke/EndInvoke使用线程池来执行。应该没有任何性能差异,因为Delegate.BeginInvoke和ThreadPool.QueueUserWorkItem都将在线程池线程上执行。最大的区别在于,如果调用BeginInvoke,则必须在某个时刻调用EndInvoke。相比之下,ThreadPool.QueueUserWorkItem是“盲目”。这有利也有弊。好处是你可以忘记它。缺点是除非你在任务完成时添加自己的同步/通知机制,否则没有办法知道。以上是C#学习教程:QueueUserWorkItem()和BeginInvoke()有什么区别,用于执行不需要返回类型的异步活动。分享所有内容,如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: