以下两段代码有什么区别?使用第二个问题会有任何问题吗?
情景1:
private void Log(Exception e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Log), e);
}
private void Log(object obj)
{
Exception e = (Exception)obj;
Logger.Log(e);
}
情景2
private void Log(Exception e)
{
ThreadPool.QueueUserWorkItem(
(obj) =>
{
Logger.Log(e);
});
}
在方案2中,我没有将异常作为参数传递给ThreadPool。如何发生异常对象的线程编组?会有问题吗?这样做有什么限制?最大的优点是您可以非常轻松地传递任意数量的参数。
答案 0 :(得分:14)
唯一的区别是,在场景二中,您正在关闭e
变量,该变量有效地将堆栈变量e
移动到移动到堆的自定义类型中,这样您就不会丢失它
我认为这应该可以正常工作。
编辑:至于性能,两种情况之间不应存在显着差异。在方案1中,您已将异常作为state
传递给QueueUserWorkItem
方法,该方法在内部将该异常引用移动到堆上。唯一的开销是当你使用一个闭包时,编译器会为你创建一个类型,并将任何捕获的变量存储为该类型的字段。
答案 1 :(得分:1)
请注意,您可以使用匿名方法执行相同的操作,而不是Lambda,它也适用于C#2.0:
ThreadPool.QueueUserWorkItem(delegate(Object e)
{
Logger.Log(e as Exception);
});