Асинхронный обмен данными по сети в C# по протоколу TCP (делаем сервер асинхронным)

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

В этой статье мы будем решать вторую проблему путём превращения «обычного» сервера, который был написан в одной из предыдущих статей [1] в асинхронный.

Сразу отметим, что здесь мы не будем затрагивать вопросы касающиеся непосредственно обмена данными по сети. Они подробно описаны в [1] и в рамках наших сегодняшних доработок мы их практически не коснёмся. Поэтому, если вы не знакомы с основными принципами работы с TCP в C#, рекомендуется вначале прочитать статью [1] (ссылка дана в конце).

Доработаем алгоритм серверной части из [1].

Добавим поле, отвечающее за «включение» и «выключение» серверной части (рекомендуется по умолчанию присваивать ему значение true).

Для того чтобы «включить» или «выключить» работу серверной части будем присваивать этому полю значение true или false соответственно.

Далее нам предстоит самое сложное. Заменить метод AcceptTcpClient класса TcpListener на метод этого же класса под названием AcceptTcpClientAsync и доработать алгоритм серверной части для корректной обработки значения поля run.

Понять, что сделано и, главное, с какой целью в данном случае проще всего на конкретном примере.

Ниже приведён уже доработанный пример серверной части из [1]. Внесённые изменения и их смысл поясняются в комментариях к коду.

 

Если сравнить с исходным вариантом, то изменений в коде не так уж и много, но в то же время работа алгоритма и приложения, где он используется, меняется кардинально. Теперь последнее не будет «зависать» после запуска бесконечного цикла. Более того, бесконечный цикл по своей сути перестал быть бесконечным. Работой алгоритма теперь можно управлять.

«Включение» серверной части можно выполнить следующим образом:

Или так (альтернативный вариант для C# 7.0 и выше):

«Отключение»:

Также стоит отметить, что в целом материал данной статьи применим для C# 5.0 (.NET Framework 4.5) и выше. В предыдущих версиях (4.0 и ниже) класс Task, а также операторы async/await отсутствуют. Для этих версий необходимо использовать низкоуровневую реализацию на основе Thread. Последняя в данной статье не рассматривается по причине глубокого морального устаревания данного подхода.

Источники
  1. Обмен данными по сети в C# (протокол TCP)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *