Правильное общение Task между собой

336
23 февраля 2017, 23:22

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

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

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

Answer 1

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

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

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

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

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

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

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

READ ALSO
Как запустить скрытое окно?

Как запустить скрытое окно?

Дело в том, что для IntPtr мне нужно создать отдельное окно, в рамках MVVM я не могу использовать основное тк

321
Применение и значение ключевого слова volatile

Применение и значение ключевого слова volatile

Если читать горячо любимый msdn можно найти следующую формулировку:

333
Вывод с двух коллекций одновременно

Вывод с двух коллекций одновременно

У меня есть две коллекции, которые нужно вывести в одном циклеКак мне лучше всего это реализовать? Можно ли использовать foreach или нет?

313