Должна ли запись в NetworkStream выполняться асинхронно

#c# #multithreading #sockets #tcp #client-server

#c# #многопоточность #сокеты #tcp #клиент-сервер

Вопрос:

Учитывая, что NetworkStream.Write() это блокирующий вызов, должен ли такой метод, как SendMessage() , создать новый поток для выполнения операции записи или SendMessage() метод должен блокироваться до отправки сообщения или возникновения исключения?

Интуиция подсказывает мне, что разумно заблокировать этот метод, но, глядя на действительно хороший пример сокетов в C #, я обнаруживаю, что они создают новый поток. Основная проблема, которую я вижу при создании другого потока, заключается в обработке ошибок.

PS: Я знаю об асинхронных версиях Write, Read и так далее, Но нахожу IAsyncResult довольно запутанным и в настоящее время воздерживаюсь от использования этих опций.

Комментарии:

1. На самом деле я бы просто научился использовать асинхронные версии метода. Это также поможет вам позже, если вам когда-нибудь понадобится выполнять асинхронные веб-запросы make, поскольку модель та же. Кроме того, если вы хотите перейти на Silverlight development, они предоставляют только асинхронные методы для некоторой функциональности.

Ответ №1:

Если вы вызываете SendMessage() поток пользовательского интерфейса, он заблокирует его, и ваше приложение «зависнет». Вместо создания нового потока каждый раз, когда вы хотите отправить данные, используйте ThreadPool.QueueUserItem(o => SendMessage()) или Task.Factory.StartNew(() => SendMessage()) из библиотеки Task Parallel в .NET 4.0

Если ваше приложение обслуживает клиентов и вы создаете новый поток для каждого клиента, то SendMessage() можете заблокировать, если вы не хотите выполнять другую работу при отправке данных клиенту.

Создание нового потока для каждого клиента имеет один недостаток: множество потоков будут потреблять много ресурсов, и большую часть времени эти потоки будут простаивать, в то время как они могли бы тем временем обслуживать других клиентов. Если вы хотите создать высокопроизводительное серверное приложение, вам следует изучить асинхронное программирование.

Проверьте асинхронный CTP. Это позволит вам писать асинхронный код, который выглядит как синхронный код, без беспорядочных обратных вызовов

 public async void SendMessage()
{
    try {
        await socket.WriteAsync(buffer, 0, buffer.Length);
    } catch (...) {
        // handle it
   }
}
  

Теперь функция SendMessage () не будет блокироваться, потому что она будет выполняться асинхронно, и это совсем не выглядит страшно!

Ответ №2:

Я настоятельно рекомендую вам взглянуть на библиотеку параллельных задач.

Вы можете создать задачу из любого асинхронного шаблона в current .net.

Задача будет выполняться в пуле потоков, а исключения будут автоматически маршалироваться из других потоков.