Потоки и лямбда-выражения - PullRequest
10 голосов
/ 08 мая 2009

В чем разница между двумя фрагментами кода ниже? Будут ли проблемы с использованием второго?

Сценарий 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 ]

14 голосов
/ 08 мая 2009

Единственное отличие состоит в том, что во втором сценарии вы закрываете переменную e, которая эффективно перемещает переменную стека e в пользовательский тип, который перемещается в кучу, чтобы вы не потеряли его.

Я думаю, это должно работать нормально.

Редактировать: Что касается производительности, то не должно быть существенной разницы между двумя сценариями. В сценарии 1 вы уже передаете исключение как state методу QueueUserWorkItem, который внутренне перемещает эту ссылку исключения в кучу. Единственное преимущество заключается в том, что при использовании замыкания компилятор создает для вас тип и сохраняет любые захваченные переменные в виде полей этого типа.

1 голос
/ 08 мая 2009

Заметим, что вместо лямбды вы можете сделать то же самое с анонимным методом, и это также будет работать в C # 2.0:

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