Связь в ASP.NET Core

Ситуация:

Мне нужно создать какую-то управляющую часть связи через Modbus TCP/IP в моем проекте ASP.NET Core.

Связь с Modbus работает правильно, но мне нужно постоянно считывать некоторые адреса Modbus, и мне нужно установить для них интервал. У меня есть такая структура для этого в db.

Теперь у меня есть singleton с именем CommunicationRepository, который является таким контроллером для этого протокола и имеет методы для чтения из модуля, записи в модуль, структуры для данных из модулей и т. д. и создания CommunicationRunners.

Диаграмма репозитория связи

CommunicationRunner - это то, что может подождать, пока истечет интервал, а затем запустить делегата из CommunicationRepository, который затем прочитает конкретный адрес Modbus.

Диаграмма CommunicationRunner

Проблема: теперь это делается асинхронно, что замедляет все остальное — навигацию по странице, ответы от веб-API и т. д. Конечно, эта проблема распознается через небольшие промежутки времени (например, 10 мс).

Как я могу сделать это более стабильным, не глючным? Должен ли я использовать потоки? Если, то как именно?

Буду признателен за примеры кода.

Спасибо и взгляните на изображения.


person David Pavelka    schedule 09.05.2017    source источник
comment
Теперь это делается асинхронно, что замедляет все остальное ‹‹ Значит ли это, что он выполняется во время запроса пользователя?? Сначала это звучало как планировщик, но приведенное выше указывает, что это не так. Если он работает исключительно в фоновом режиме и никоим образом не связан с запросом пользователя, просто поместите эту часть вашего приложения в консольное приложение и запустите его как отдельный процесс в фоновом режиме (также известный как фоновые рабочие процессы)   -  person Tseng    schedule 09.05.2017
comment
Он не выполняется во время запроса пользователя. Предполагается, что он работает в фоновом режиме. Хорошо, это звучит здорово. Я сделаю это как новый проект в решении. Отличное предложение - Спасибо. И я могу использовать .net core, так что он останется кроссплатформенным = идеальным.   -  person David Pavelka    schedule 09.05.2017
comment
И что я должен здесь использовать? Могу ли я использовать потоки для каждого бегуна? Что ты предлагаешь?   -  person David Pavelka    schedule 09.05.2017
comment
Сильно зависит от конкретных требований. Вы можете запускать основной планировщик в основном потоке и запускать новые потоки для каждой задачи (запускаться по истечении интервала). Если вы используете отслеживание (сущностей DbContext), вам могут понадобиться некоторые фабрики для создания нового экземпляра DbContext (или новой области действия для всей задачи с использованием IServiceScopeFactory, таким образом все ресурсы освобождаются после завершения инициированного действия).   -  person Tseng    schedule 09.05.2017
comment
Или создайте команды (сообщения poco с информацией) и реализацию ICommandHandler<TCommand>, которая обрабатывает эту команду, используйте шину сообщений, чтобы распределить ее между многими серверами... способ объяснить все это подробно, поскольку это зависит от каждого случая.   -  person Tseng    schedule 09.05.2017
comment
Приятно слышать об этих вариантах. Я могу иметь его только на одном сервере, и я не использую базу данных в этой связи (только в первый раз, чтобы получить то, что нужно прочитать по Modbus и получить интервалы и т. д.). Поэтому я думаю, что потоки для каждой задачи - правильный способ сделать это. Спасибо много.   -  person David Pavelka    schedule 09.05.2017