Тайм -ауты на асинхронном общении с SocketAsynceventargs
-
26-10-2019 - |
Вопрос
Я использую SocketAsynceventargs для общения с сотнями оборудования (большинство из них через GPR). Иногда некоторые из них перестают реагировать, и, похоже, у меня нет возможности разобраться с операцией, поскольку в документации говорится, что варианты тайм -аута (т.е. SocketOptionName.sendTimeout) не работает над асинхронным общением.
Я ищу способ проверки тайм -аутов при отправке/получении/ConnectAsync. Он не должен блокировать поток (поэтому, вызывая somemonitor.waitone (когда -то аут -зал), и я не хочу создавать экземпляр таймера за операцию (поскольку количество оборудования наверняка увеличится).
Есть советы по этому поводу?
Решение
Вот как я это сделал (в целом мне не понравилось решение):
Идея состоит в том, чтобы иметь один таймер, который при увольнении проверяет все ожидающие операции на тайм -ауты. Я создал интерфейс, который внедряет мой асинхровый клиент:
public interface ITimeoutable {
event Action<ITimeoutable, Operation> Begin;
event Action<ITimeoutable, Operation> End;
void DoTimeout(Operation operation);
}
где операция перечислена, определяется как:
public enum Operation {
Connect,
Send,
Receive,
Disconnect
}
Итак, клиент поднимает Begin
событие при запуске асинхронной операции и повышает End
событие, когда заканчивает это. С другой стороны, я создал TimeoutManager, который имеет коллекцию асинхровых клиентов и словарь с операциями и мгновение, когда они были начаты. Когда создается новый клиент, он зарегистрирован в TimeoutManager
, который подписывается на события. А TimeoutManager
использует System.Threading.Timer
Чтобы проверить, какие операции пришли время. Если у него есть тайм -аут, то он вызывает DoTimeout
Метод (из ITimeoutable
интерфейс).
Это довольно сложный код, и мне это не нравится. Но это работает.