Как отменить Socket.ReceiveFromAsync ()? - PullRequest
1 голос
/ 07 марта 2019

Я работаю с dotnet core 2.2 и у меня есть следующий прослушиватель UDP:

var socket = new Socket(ep.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
while (true)
{
    var result = await socket.ReceiveFromAsync(...);
}

Теперь в некоторых случаях я хотел бы прервать вызов ReceiveFromAsync().Но, похоже, что в отличие от случая TCP (т. Е. ReceiveAsync()) ReceiveFromAsync() не допускает перегрузку CancellationToken.

. Один вариант - использовать Task.Delay(-1, ct); вместе с Task.WhenAny()/Task.WhenAll().Но я думаю, что это решение приводит к утечке памяти, верно?Я имею в виду, что .ReceiveFromAsync() вызов все еще «существует», если прерван, просто в фоновом режиме.Также может привести к нарушению логики, потому что такой вызов будет читать UDP-пакет и впоследствии отбрасывать его?Или мои рассуждения неверны?

Другой идеей было бы иметь фонового работника, который читает из сокета UDP и ставит в очередь каждый пакет.И здесь не может быть никакого перерыва.Затем я читал из очереди и прерывал этот вызов.Это бы сработало, но определенно требует определенных усилий.Я вижу следующие проблемы: безопасность и производительность потоков.

Есть ли более понятный / простой способ справиться с этой ситуацией?

1 Ответ

1 голос
/ 09 марта 2019

Для «не подлежащих отмене» запросов ввода / вывода стандартным шаблоном в Windows является закрытие основного дескриптора - в данном случае сокета.Обычно это приводит к тому, что любые асинхронные (или синхронные) операции завершаются с кодом ошибки.

В вашей ситуации - «приостановка» приемника UDP - я думаю, что этот подход особенно имеет смысл.UDP-сокеты в любом случае не представляют собой открытые соединения, поэтому закрытие сокета является лучшим решением.

Что касается Task.Delay с Task.WhenAny, ваши опасения совершенно верны.Подход Task.Delay + Task.WhenAny отменяет только wait операции, а не саму операцию.В частности, он не отменял бы прием UDP, и эта не полученная операция приема UDP может получить пакет, который затем будет «потерян», поскольку ваше приложение проигнорирует его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...