C # - Какой лучший способ использовать TcpListener (асинхронный) - PullRequest
0 голосов
/ 27 июня 2019

Я бы создал tcp-сервер с TcpListener, но я не знаю, какое решение лучше для этого сделать. Я попробовал с 3 примерами. Смотри ниже.

Пример 1 (Я использовал BeginAcceptTcpClient)

class Program
  {
    static void Main(string[] args)
    {
      var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
      var listener = new TcpListener(endPoint);

      listener.Start();

      AcceptTcpClient(listener);
      while (true)
      {
      }
    }

    public static void AcceptTcpClient(TcpListener listener)
    {
      listener.BeginAcceptTcpClient(ClientConnected, listener);
    }

    public static void ClientConnected(IAsyncResult asyncResult)
    {
      var listener = (TcpListener)asyncResult.AsyncState;
      var client = listener.EndAcceptTcpClient(asyncResult);
      AcceptTcpClient(listener);

      DoAsync(client);
    }
  }

Пример 2 (Я использовал BeginAcceptTcpClient с AutoResetEvent)

class Program1
  {
    private static readonly AutoResetEvent CONNECTION_WAIT_HANDLE = new AutoResetEvent(false);
    static void Main(string[] args)
    {
      var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
      var listener = new TcpListener(endPoint);

      listener.Start();

      while (true)
      {
        listener.BeginAcceptTcpClient(ClientConnectedHandle, listener);
        CONNECTION_WAIT_HANDLE.WaitOne();
        CONNECTION_WAIT_HANDLE.Reset();
      }
    }

    public static void ClientConnectedHandle(IAsyncResult asyncResult)
    {
      var listener = (TcpListener)asyncResult.AsyncState;
      var client = listener.EndAcceptTcpClient(asyncResult);
      CONNECTION_WAIT_HANDLE.Set();

      DoAsync(client);
    }
  }

Пример 3 (Я использовал AcceptTcpClientAsync)

class Program2
  {
    static async Task Main(string[] args)
    {
      var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4567);
      var listener = new TcpListener(endPoint);

      listener.Start();

      while (true)
      {
        var client = await listener.AcceptTcpClientAsync();
        DoAsync(client);
      }
    }

    public static void AcceptTcpClient(TcpListener listener)
    {
      listener.BeginAcceptTcpClient(ClientConnected, listener);
    }

    public static void ClientConnected(IAsyncResult asyncResult)
    {
      var listener = (TcpListener)asyncResult.AsyncState;
      var client = listener.EndAcceptTcpClient(asyncResult);
      AcceptTcpClient(listener);

      DoAsync(client);
    }
  }

Я думаю, что лучшее решение - последнее (Пример 3), но я не уверен. Что вы думаете об этом?

1 Ответ

0 голосов
/ 27 июня 2019

Пример 3 использует основанный на задачах асинхронный шаблон (TAP), который является рекомендуемым шаблоном асинхронного проектирования для новой разработки, как указано в документах .

TAP использует один метод для представления начала и завершения асинхронной операции.Это контрастирует с шаблоном модели асинхронного программирования (APM или IAsyncResult) и с шаблоном асинхронного программирования на основе событий (EAP).APM требует методов Begin и End.Для EAP требуется метод с суффиксом Async, а также одно или несколько событий, типы делегатов обработчиков событий и производные от EventArg типы.Асинхронные методы в TAP включают суффикс Async после имени операции для методов, которые возвращают ожидаемые типы, такие как Task, Task, ValueTask и ValueTask.

...