2

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

Какие существуют способы передачи данных в существующий Task обработки данных?

Самое банальное, это общение поле класса. Это правильно?

iluxa1810
  • 24,899

1 Answers1

5

Нет, поля класса для такого использовать - неправильно!

Задача - это элемент ФП (функционального программирования). Она должна получать входные параметры через замыкание - а выдавать результат через возвращаемое значение. Изменяемое поле класса не является ни тем, ни другим.

Нарушение этого принципа приводит к тому, что вам теперь нужно беспокоиться о синхронизации разных потоков. А синхронизация потоков в многопроцессорной среде - это не то, чему можно научиться по-быстрому.


Ваша задача является классической задачей Producer-Consumer (поставщик-потребитель). Более подробно решения этой задачи можно увидеть тут: Имплементация Producer/Consumer pattern.

Если коротко - то вам надо либо использовать блокирующую очередь, BlockingCollection - либо BufferBlock из библиотеки TPL Dataflow для асинхронной обработки.

Также вместо задачи-обработчика можно создать ActionBlock и подцепить его к BufferBlock.

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

Pavel Mayorov
  • 58,537
  • 1
    Стоит еще сказать, что таски для этого не преднозначены. – Fynivx Feb 22 '17 at 09:34
  • @Fynivx вообще говоря, таски предназначены для любых процессов, у которых надо проверять результат. – Pavel Mayorov Feb 22 '17 at 09:40
  • 2
    Ну, во-первых, очевидно, что не для всех. Во-вторых, я имел ввиду, что таски - абстракция более высокого уровня, и используя их вот так, в лоб, можно огрести кучу проблем. В .NET есть более специфичные примитивы для данной проблемы - System.Threading.Tasks.Dataflow. – Fynivx Feb 22 '17 at 10:10
  • @Fynivx а что, Dataflow не через таски работает? :) – Pavel Mayorov Feb 22 '17 at 10:47
  • @PavelMayorov через таски, но сам таск нужен для исполнения однйо задачи. Задать вход -> получить выход. Dataflow же используя таски и в том числе и BlockinngCollection позволяет повысить уровень абстракции для решаемых задач. – neftedollar Feb 22 '17 at 12:06
  • @PavelMayorov через таски, но его разработчики наверняка в курсе, что таски в .Net - это просто удобная абстракция два выполнения асинхронных операций, и ничего больше, и что в работе с ними есть куча вопросов, о которых должен думать разработчик. Готова ли ваша реализация обработки потоков данных к тому, например, что таск запустится на удаленной машине? А ведь такое может произойти. – Fynivx Feb 22 '17 at 15:46