此post表示当您在委托上调用BeginInvoke
方法时,始终需要调用EndInvoke
方法。另一个post支持它并建议将班级BackgroundWorker
作为替代。
我使用ILSpy反编译BackgroundWorker
我发现实际上,EndInvoke
从未在此类中调用,即使它确实使用BeginInvoke
代表。
这是否意味着BackgroundWorkder
执行不当,或者调用EndInvoke
不是必要的?
(丢失异常的问题无关紧要,因为调用的整个方法都包含在try-catch块中)
关于类似问题:有一个明确的理由说明BeginInvoke
在BackgroundWorker
的实施中选择了ThreadPool.QueueUserWorkItem()
而不是BackgroundWorker
?
修改:可以查看{{1}}的源代码here。
答案 0 :(得分:1)
我找了一会儿幕后男人。 CLR具有SynchronizationContext类的秘密知识,因此从技术上讲它可以在这里涉及。绝对没有找到。
直到我首先检查了我应该做了什么,实际上验证了EndInvoke()是否需要声明:
using System;
class Program {
static void Main(string[] args) {
Action d = null;
d = new Action(() => {
d.BeginInvoke(null, null);
});
d();
Console.ReadLine();
}
}
像大佬一样奔跑,消耗大量手柄。但它不会爆炸,它们永远不会超过〜2000并且内存使用率完全稳定。
因此,调整委托者的EndInvoke()是必需的,也许是适当的。如果你有先验知识,委托目标不会做任何异常,比如调用另一个AppDomain,运行本机代码或激活远程代码,那么你就可以逃避不调用EndInvoke()。 BackgroundWorker可以提供的保证。我永远不能将这种说法仅仅视为SO用户。但微软这样做,所以一定没问题。源代码中的注释会很好。