Как делают Реактивная Платформа, PLINQ, TPL и Параллельные Расширения касаются друг друга?

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

  • Реактивная платформа,
  • PLINQ (параллельны LINQ),
  • TPL (библиотека параллели задачи) и
  • Параллельные расширения.

Теперь они все, кажется, продукты Microsoft, и они все, кажется, предназначаются для сценариев асинхронного программирования или параллельного программирования для.NET. Но не совсем ясно, что на самом деле каждый из них и как они связаны друг с другом. Некоторые могли бы на самом деле быть тем же самым.

В нескольких словах кто-либо может внести ясность на том, что что?

66
задан bitbonk 14 December 2015 в 20:38
поделиться

2 ответа

PLINQ (Parallel Linq) - это просто новый способ написания обычных запросов Linq, чтобы они выполнялись параллельно - другими словами, Framework будет автоматически позаботится о выполнении вашего запроса в нескольких потоках, чтобы они завершились быстрее (т. е. с использованием нескольких ядер ЦП).

Например, предположим, что у вас есть связка строк, и вы хотите получить все те, которые начинаются с буквы «А». Вы можете написать свой запрос так:

var words = new[] { "Apple", "Banana", "Coconut", "Anvil" };
var myWords = words.Select(s => s.StartsWith("A"));

И это прекрасно работает. Однако, если у вас было 50 000 слов для поиска, вы могли бы воспользоваться тем фактом, что каждый тест является независимым, и разделить его на несколько ядер:

var myWords = words.AsParallel().Select(s => s.StartsWith("A"));

Это все, что вам нужно сделать, чтобы превратить обычный запрос в параллельный. который работает на нескольких ядрах.Довольно аккуратно.


TPL (Библиотека параллельных задач) является своего рода дополнением к PLINQ, и вместе они составляют параллельные расширения. В то время как PLINQ в значительной степени основан на функциональном стиле программирования с без побочных эффектов, побочные эффекты - это именно то, для чего предназначен TPL. Если вы хотите на самом деле выполнять работу параллельно, а не просто искать / выбирать объекты параллельно, вы используете TPL.

TPL по сути является классом Parallel , который предоставляет перегрузки For , Foreach и Invoke . Invoke немного похож на постановку задач в очередь в ThreadPool , но немного проще в использовании. IMO, более интересными являются биты для и Foreach . Так, например, предположим, что у вас есть целая куча файлов, которые вы хотите сжать. Вы можете написать обычную последовательную версию:

string[] fileNames = (...);
foreach (string fileName in fileNames)
{
    byte[] data = File.ReadAllBytes(fileName);
    byte[] compressedData = Compress(data);
    string outputFileName = Path.ChangeExtension(fileName, ".zip");
    File.WriteAllBytes(outputFileName, compressedData);
}

Опять же, каждая итерация этого сжатия полностью независима от других. Мы можем ускорить это, выполнив несколько из них одновременно:

Parallel.ForEach(fileNames, fileName =>
{
    byte[] data = File.ReadAllBytes(fileName);
    byte[] compressedData = Compress(data);
    string outputFileName = Path.ChangeExtension(fileName, ".zip");
    File.WriteAllBytes(outputFileName, compressedData);
});

И снова, это все, что нужно для распараллеливания этой операции. Теперь, когда мы запускаем наш метод CompressFiles (или как бы мы его ни называли), он будет использовать несколько ядер ЦП и, вероятно, завершит работу за половину или 1/4 времени.

Преимущество этого метода по сравнению с простым помещением всего этого в ThreadPool состоит в том, что он на самом деле выполняется синхронно .Если бы вы использовали вместо этого ThreadPool (или просто экземпляры Thread ), вам нужно было бы придумать способ узнать, когда все задачи выполнены, и пока этот не ужасно сложный, это то, с чем многие люди склонны ошибаться или, по крайней мере, иметь с этим проблемы. Когда вы используете класс Parallel , вам действительно не нужно об этом думать; аспект многопоточности скрыт от вас, все это делается за кулисами.


Реактивные расширения (Rx) - это совсем другое дело. Это другой взгляд на обработку событий. На самом деле есть много материала, чтобы охватить это, но, чтобы короче, вместо того, чтобы связывать обработчики событий с событиями, Rx позволяет вам обрабатывать последовательности событий как ... ну, последовательности ( IEnumerable ). Вы можете обрабатывать события итеративно, вместо того, чтобы запускать их асинхронно в случайное время, когда вы должны постоянно сохранять состояние, чтобы обнаруживать серию событий, происходящих в определенном порядке.

Один из самых крутых примеров Rx, который я нашел, - это здесь . Перейдите к разделу «Linq to IObservable», где он реализует обработчик перетаскивания, который обычно является проблемой в WPF, всего в 4 строках кода. Rx дает вам композицию событий, чего вы действительно не имеете с обычными обработчиками событий, и фрагменты кода, подобные этим, также легко реорганизовать в классы поведения, которые вы можете вставить где угодно.


Вот и все.Это некоторые из более интересных функций, доступных в .NET 4.0. Конечно, есть еще несколько, но это те, о которых вы спрашивали!

95
ответ дан 24 November 2019 в 14:59
поделиться

Мне нравится ответ Ааронаута, но я бы сказал, что Rx и TPL решают разные проблемы. Часть того, что добавила команда TPL, - это примитивы потоковой передачи и значительные улучшения в строительные блоки среды выполнения, такие как ThreadPool. И все, что вы перечисляете, построено на основе этих примитивов и функций времени выполнения.

Но TPL и Rx решают две разные проблемы. TPL работает лучше всего, когда программа или алгоритм «вытягивают и помещают в очередь». Rx отлично подходит, когда программе или алгоритму необходимо «реагировать» на данные из потока (например, ввод с помощью мыши или при получении потока связанных сообщений от конечной точки, такой как WCF).

Вам понадобится концепция «единицы работы» из TPL, чтобы работать как файловая система, выполнять итерацию по коллекции или перемещаться по иерархии, например, в организационной диаграмме. В каждом из этих случаев программист может рассуждать об общем объеме работы, работа может быть разбита на фрагменты определенного размера (задачи), а в случае выполнения вычислений по иерархии задачи могут быть объединены в цепочку. . Таким образом, определенные типы работы поддаются модели «Иерархия задач» TPL и получают выгоду от улучшений сантехники, таких как отмена (см. Видео Channel 9 на CancellationTokenSource).TPL также имеет множество регуляторов для специализированных областей, таких как обработка данных в режиме, близком к реальному времени.

Rx - это то, что в конечном итоге должно использовать большинство разработчиков. Именно так приложения WPF могут «реагировать» на внешние сообщения, такие как внешние данные (поток IM-сообщений для IM-клиента) или внешний ввод (например, пример перетаскивания мышью, связанный с Aaronaught). Под покровом Rx использует потоковые примитивы из TPL / BCL, потокобезопасные коллекции из TPL / BCL и объекты времени выполнения, такие как ThreadPool. На мой взгляд, Rx - это «высший уровень» программирования для выражения ваших намерений.

Еще предстоит увидеть, сможет ли средний разработчик увлечься набором намерений, которые вы можете выразить с помощью Rx. :)

Но я думаю, что в следующие пару лет TPL против Rx станет следующей дискуссией, как LINQ-to-SQL против Entity Framework. В одном домене есть две разновидности API, которые специализируются на разных сценариях, но во многом пересекаются. Но в случае TPL и Rx они фактически знают друг друга, и есть встроенные адаптеры для составления приложений и совместного использования обеих платформ (например, подача результатов из цикла PLINQ в поток IObservable Rx). Для людей, которые не занимались параллельным программированием, есть масса возможностей для ускорения обучения.

Обновление: я использую и TPL, и RxNet в своей обычной работе в течение последних 6 месяцев (из 18 месяцев с момента моего первоначального ответа). Мои мысли о выборе TPL и / или RxNet в WCF-сервисе среднего уровня (корпоративный LOB-сервис): http://yzorgsoft.blogspot.com/2011/09/middle-tier-tpl-andor-rxnet.html

30
ответ дан 24 November 2019 в 14:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: