Поток BeginAcceptTcpClient безопасен?C # - PullRequest
0 голосов
/ 02 мая 2019

Я начинаю с мира TCP Asynchronous серверов и ищу способ обработки нескольких соединений одновременно. Я обнаружил, что BeginAcceptTcpClient может быть решением.

Я нашел двавозможные способы использования BeginAcceptTcpClient при запуске сервера для получения соединений.Мой вопрос будет таким: какая разница между этими двумя и какая из них будет поточно-ориентированной (или, если они обе).

FIRST WAY

Вызов BeginAcceptTcpClient внутри обратного вызова.

static TcpListener socket = new TcpListener(IPAddress.Any, 4444);

public static void InitNetwork()
        {
            socket.Start();
            socket.BeginAcceptTcpClient(new AsyncCallback(OnClientConnect), null);
        }

private static void OnClientConnect(IAsyncResult ar)
        {
            TcpClient newclient = socket.EndAcceptTcpClient(ar);
            socket.BeginAcceptTcpClient(new AsyncCallback (OnClientConnect), null); // Call the Callback again to continue listening

            HandleClient.CreateConnection(newclient); //Do stuff with the client recieved
        }

ВТОРОЙ ПУТЬ

Использование AutoResetEvent.

static TcpListener socket = new TcpListener(IPAddress.Any, 4444);
private AutoResetEvent connectionWaitHandle = new AutoResetEvent(false);

public static void InitNetwork()
        {
            socket.Start();

            while(true)
            {
              socket.BeginAcceptTcpClient(new AsyncCallback(OnClientConnect), null);
              connectionWaitHandle.WaitOne(); // Wait until a client has begun handling an event
              connectionWaitHandle.Reset(); // Reset wait handle or the loop goes as fast as it can (after first request)
            }

        }

private static void OnClientConnect(IAsyncResult ar)
        {
            TcpClient newclient = socket.EndAcceptTcpClient(ar);
            connectionWaitHandle.Set(); //Inform the main thread this connection is now handled

            HandleClient.CreateConnection(newclient);  //Do stuff with the client recieved
        }

Я ищу правильный путь кобрабатывать несколько соединений (был потокобезопасным).Я ценю любой ответ.

1 Ответ

0 голосов
/ 02 мая 2019

Я предпочитаю AcceptTcpClientAsync.Это проще, чем BeginAcceptTcpClient и все еще асинхронный.

public async Task InitNetwork()
{
    while( true )
    {
        TcpClient newclient = await socket.AcceptTcpClientAsync();
        Task.Run( () => HandleClient.CreateConnection( newclient ) );
    }
}

Внутренне, AcceptTcpClientAsync использует Task.Factory.FromAsync, чтобы обернуть BeginAcceptTcpClient и EndAcceptTcpClient в объект Task.

public Task<TcpClient> AcceptTcpClientAsync()
{
    return Task<TcpClient>.Factory.FromAsync(BeginAcceptTcpClient, EndAcceptTcpClient, null);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...