线程和lambda表达式

时间:2009-05-08 16:48:53

标签: c# .net multithreading lambda threadpool

以下两段代码有什么区别?使用第二个问题会有任何问题吗?

情景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。如何发生异常对象的线程编组?会有问题吗?这样做有什么限制?最大的优点是您可以非常轻松地传递任意数量的参数。

2 个答案:

答案 0 :(得分:14)

唯一的区别是,在场景二中,您正在关闭e变量,该变量有效地将堆栈变量e移动到移动到堆的自定义类型中,这样您就不会丢失它

我认为这应该可以正常工作。

编辑:至于性能,两种情况之间不应存在显着差异。在方案1中,您已将异常作为state传递给QueueUserWorkItem方法,该方法在内部将该异常引用移动到堆上。唯一的开销是当你使用一个闭包时,编译器会为你创建一个类型,并将任何捕获的变量存储为该类型的字段。

答案 1 :(得分:1)

请注意,您可以使用匿名方法执行相同的操作,而不是Lambda,它也适用于C#2.0:

ThreadPool.QueueUserWorkItem(delegate(Object e) 
    { 
        Logger.Log(e as Exception); 
    });