Ответ 1
Прежде чем развертывать решение в среде ASP.NET, я предлагаю вам изменить вашу архитектуру: IIS может приостанавливать потоки в ASP.NET для собственного использования после обработки запроса, чтобы ваша задача могла быть незавершенной. Лучшим подходом является создание отдельного демона службы Windows, который обрабатывает поток данных.
Теперь вернемся к потоку данных TPL.
Мне нравится библиотека TPL Dataflow, но документация - настоящий беспорядок. Единственный полезный документ, который я нашел, - Введение в поток данных TPL.
В нем есть некоторые подсказки, которые могут быть полезны, особенно те, которые касаются настроек конфигурации (я предлагаю вам исследовать реализацию собственного TaskScheduler
с использованием вашей собственной реализации TheadPool
и MaxMessagesPerTask
), если вы необходимо:
Встроенные блоки потока данных настраиваются, при этом обеспечивается большой контроль над тем, как и где блоки выполняют свою работу. Вот некоторые ключевые кнопки, доступные разработчику, все из которых отображаются через класс
DataflowBlockOptions
и его производные типы (ExecutionDataflowBlockOptions
иGroupingDataflowBlockOptions
), экземпляры которых могут быть предоставлены блокам во время строительства.
-
Настройка TaskScheduler, как упоминалось в @i3arnon:
По умолчанию блок данных блокирует работу с расписанием
TaskScheduler.Default
, которая нацелена на внутренние действия .NETThreadPool
. -
MaxDegreeOfParallelism
По умолчанию используется значение
1
, что означает, что в блоке может быть только одна вещь. Если установлено значение, превышающее1
, это количество сообщений может обрабатываться одновременно блоком. Если установлено значениеDataflowBlockOptions.Unbounded (-1)
, любое количество сообщений может обрабатываться одновременно, причем максимум автоматически управляется базовым планировщиком, предназначенным блоком потока данных. Обратите внимание, чтоMaxDegreeOfParallelism
является максимальным, а не обязательным. -
MaxMessagesPerTask
TPL Dataflow фокусируется на эффективности и управлении. Там, где есть необходимые компромиссы между ними, система стремится обеспечить качество по умолчанию, но также позволяет разработчику настраивать поведение в соответствии с конкретной ситуацией. Одним из таких примеров является компромисс между эффективностью и честностью. По умолчанию блоки потока данных пытаются минимизировать количество объектов задачи, необходимых для обработки всех их данных. Это обеспечивает очень эффективное выполнение; до тех пор, пока у блока есть данные, которые могут быть обработаны, блокировка задач останется для обработки доступных данных, только уходит в отставку, когда больше нет данных (пока данные снова не появятся, и в этот момент больше задач будет развернуто). Однако это может привести к проблемам справедливости. Если система в настоящее время насыщена обработкой данных из заданного набора блоков, а затем данные поступают в другие блоки, эти последние блоки будут либо ждать, пока первые блоки закончат обработку, прежде чем они смогут начать, или, альтернативно, риск переназначение системы. Это может быть или не быть правильным поведением для данной ситуации. Чтобы решить эту проблему, существует опция
MaxMessagesPerTask
. По умолчанию он равенDataflowBlockOptions.Unbounded (-1)
, что означает, что максимального значения нет. Однако, если установлено положительное число, это число будет представлять максимальное количество сообщений, которые данный блок может использовать для обработки одной задачи. Как только это ограничение достигнуто, блок должен удалить задание и заменить его репликой для продолжения обработки. Эти реплики обрабатываются справедливо в отношении всех других задач, запланированных планировщику, что позволяет блокам достичь скромности между ними. В крайнем случае, еслиMaxMessagesPerTask
установлено в 1, для каждого сообщения будет использоваться одна задача, обеспечивающая предельную справедливость при потенциальном расходе большего количества задач, чем это могло бы быть в противном случае. -
MaxNumberOfGroups
Блоки группировки способны отслеживать количество групп, которые они создали, и автоматически завершают себя (отклоняя дальнейшие предлагаемые сообщения) после того, как было создано такое количество групп. По умолчанию количество групп DataflowBlockOptions.Unbounded(-1), но может быть явно установлено значение больше единицы.
-
CancellationToken
Этот токен контролируется во время жизни блоков потока данных. Если запрос на отмену доходит до завершения блоков, блок прекратит работу как можно более вежливо и быстро.
-
Жадный
По умолчанию целевые блоки жадные и хотят, чтобы все данные им предлагались.
-
BoundedCapacity
Это предел количества элементов, которые блок может хранить и иметь в полете в любой момент времени.