Улучшения многопоточности в .NET 4 - PullRequest
28 голосов
/ 24 апреля 2010

Я слышал, что команда .NET 4 добавила в среду новые классы, которые делают работу с потоками лучше и проще.

По сути, вопрос в том, какие новые способы запуска многопоточных задач добавлены в .NET 4 и для чего они предназначены?

UPD: Просто чтобы прояснить ситуацию, я не ищу единственного способа запуска параллельных задач в .NET 4, я хочу узнать, какие из добавленные, и, если возможно, в какой ситуации каждый из них будет лучше всего подходить для ..

Ответы [ 3 ]

36 голосов
/ 25 апреля 2010

Из-за отсутствия ответов я решил оценить ответы, которые я изучил ниже. Как сказал @Scott, в .NET 4 добавлена ​​библиотека параллельных задач, которая добавляет ряд инноваций, новых методов и подходов к параллелизму.

  • Одной из первых вещей, о которых стоит упомянуть, являются методы Parallel.For и Parallel.ForEach, которые позволяют разработчику обрабатывать несколько элементов в нескольких потоках. В этом случае Framework решит, сколько потоков необходимо, и когда создавать новые потоки, а когда нет.
    Это очень простой и понятный способ распараллеливания существующего кода и повышения производительности.
  • Другим способом, несколько похожим на предыдущие подходы, является использование экстендеров PLINQ. Они берут существующее перечисление и расширяют его параллельными расширителями linq. Поэтому, если у вас есть запрос linq, вы можете легко преобразовать его в PLINQ. Это означает, что все операции над перечислимым PLINQ также будут использовать преимущества нескольких потоков, а фильтрация списка объектов с помощью, например, предложения .Where будет выполняться в нескольких потоках!
  • Одна из самых больших инноваций в TPL - новый класс Task. В некотором смысле он может выглядеть как уже хорошо известный класс Thread, но он использует преимущества нового пула потоков в .NET 4 (который был значительно улучшен по сравнению с предыдущими версиями) и гораздо более функциональный, чем обычный Thread класс. Например, вы можете связать Задачи, где задачи в середине цепочки начнутся только тогда, когда завершатся предыдущие. Примеры и подробное объяснение в скринкасте на Канале 9
  • Для улучшения работы с классами задач мы можем использовать BlockingCollection<>. Это прекрасно работает в ситуациях, когда у вас есть сценарий производитель-потребитель. У вас может быть несколько потоков, создающих некоторые объекты, которые затем будут потребляться и обрабатываться потребительскими методами. Это можно легко распараллелить и контролировать с помощью фабрики задач и коллекции блокировок. Полезный скринкаст с примерами из Канал 9
    В них также могут использоваться различные классы резервного хранилища (ConcurrentQueue, ConcurentStack, ConcurrentBag), которые являются потокобезопасными и различаются с точки зрения упорядочения элементов и производительности. Примеры и объяснения их в другом видео здесь
  • Еще одна новая вещь, которая была добавлена ​​(которая, вероятно, не является частью TPL, но в любом случае помогает нам здесь), - это класс CountdownEvent, который может помочь нам в «сценариях координации задач» (c). В основном позволяет нам ждать, пока все параллельные задачи не будут завершены. Скринкаст с примером использования на канале 9

На канале 9 вы можете увидеть несколько скринкастов и видео, помеченных «Параллельные вычисления»

15 голосов
/ 24 апреля 2010

Да, в .NET 4 добавлена ​​ параллельная библиотека задач , которая на высоком уровне добавляет поддержку:

  • выполнение параллельных циклов с Parallel.For и Parallel.ForEach
  • создание или запуск задач с использованием Parallel.Invoke или Task class
  • PLINQ (параллельно LINQ to Objects)

Ответ на обновление на исходный вопрос ...

TPL - это предпочтительный способ написания параллельных задач с использованием .NET 4. Вы по-прежнему можете создавать элементы пула потоков самостоятельно и использовать все те же "ручные" методы потоков, которые вы могли использовать ранее. Следует помнить, что весь пул потоков (и почти все, что связано с потоками) был переписан для использования преимуществ TPL. Это означает, что даже если вы создадите элемент пула потоков самостоятельно, вы все равно будете использовать TPL, даже если вы этого не знаете. Следует также помнить, что TPL гораздо более оптимизирован и будет масштабироваться более корректно в зависимости от количества доступных процессоров.

Что касается того, для какой ситуации лучше всего подходит каждый из них, то ответа «серебряная пуля» не существует. Если вы ранее ставили в очередь свой собственный элемент пула потоков (или иным образом делали что-то многопоточное), вы можете изменить эту часть своего кода, чтобы использовать TPL без каких-либо последствий.

Для таких вещей, как параллельные циклы или параллельные запросы, вам необходимо проанализировать код и выполнение этого кода, чтобы определить, целесообразно ли распараллеливать.

1 голос
/ 29 апреля 2010

Строго говоря, это C # 4.0, а не новый класс, но события теперь имеют более умную форму блокировки , которая, если я правильно понял изменение, устраняет необходимость код блокировки, как показано ниже (взято из статьи этой статьи Джона Скита):

SomeEventHandler someEvent;
readonly object someEventLock = new object();

public event SomeEventHandler SomeEvent
{
    add
    {
        lock (someEventLock)
        {
            someEvent += value;
        }
    }
    remove
    {
        lock (someEventLock)
        {
            someEvent -= value;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...