2014-01-24 2 views
2

У меня есть служба Windows .NET, которая реализует сервер сокетов с использованием парадигмы ввода-вывода асинхронного ввода-вывода BeginRead/EndRead. Теперь этот код сокета должен быть вызван в асинхронный код async/Task/await.Что происходит, когда вы используете Task.Run так сильно, что пул потоков исчерпан?

Я использовал метод запуска AsyncContext библиотеки Nito.AsyncEx 'Run, но у меня были оговорки о том, блокирует ли это вызов из EndRead, удерживая заложник рабочего потока. Совет, который я получил до my earlier question, должен был использовать Task.Run вместо Ninto.AsyncEx AsyncContext.Run. Это отправляет вызов в код async/await и немедленно возвращается. Мне пришло в голову, что при загрузке у клиентов нет отклика на то, чтобы удержать запросы от наводнения пула потоков.

Я перепрошу свой первоначальный вопрос о AsyncContext.Run от Nito.AsyncEx: он удерживает поток, на который он вызван (поток потока, вызывающий обратный вызов EndRead), или освобождает этот поток, в то время как асинхронный ввод-вывод, который вызывает вызов в фоновом режиме?

Если Nite.AsyncEx AsyncContext.Run действительно блокирует, то Task.Run представляется моим единственным выбором. Любые советы о том, как откликаться на запросы клиентов для предотвращения истощения пула потоков?

ответ

7

Цель AsyncContext.Run состоит в том, чтобы заблокировать до завершения всех асинхронных операций. Он удерживает нить до тех пор, пока это не произойдет.

Я предлагаю вам пересмотреть все предположения до сих пор:

  1. ли вам действительно нужен сокет-сервер? Есть тонн ловушек вокруг сокетов TCP/IP. Шутки в сторону. A лот из них. Есть ли какой-либо способ, которым вы можете самостоятельно использовать WebAPI?Это было бы лот легче работать, чем сервер сокетов.
  2. Зачем вам нужно подталкивать работу к потоку пула потоков? Обратный вызов End* уже вызывается в потоке пула потоков.
  3. Вы уверены, что вам нужно дросселировать? Нет кода, который может остановить достаточно мотивированную DoS-атаку.

Если вы уверены, что вам действительно нужно реализовать свой собственный сервер TCP/IP, и вы не можете сделать работу синхронно обратного вызова, и вам не нужно душить ... а затем рассмотреть Reactive Extensions или TPL Dataflow. Обе эти библиотеки имеют встроенный дополнительный дросселирование.

+0

Сервер сокетов - это требование для небольших накладных расходов для наших клиентов с несколькими и высокими пропускными способностями. Мы также поддерживаем HTTP, и этот код использует HttpTaskAsyncHandler, поэтому я не беспокоюсь о его масштабируемости и у него больше клиентов с более низкими требованиями к пропускной способности. Использование AsyncContext.Run не будет нажимать на клиента для многих наших типов запросов (они начинают/заканчивают свое ...). Мое беспокойство по поводу отклика клиента было необоснованным беспокойством ... мы контролируем, кто подключается к нашим серверам сокетов. Задача. Нужно быть в порядке. –

2

Это зависит от того, что именно делает ваше приложение. Здесь не несколько сценариев:

Вы обработка потока данных от каждого клиента

Клиентов, каждый отправить некоторые данные, ваши процессы сервера каждого сообщение, как это происходит в В этом случае, может быть нет. необходимо запустить обработку в отдельном потоке. Пока вы блокируете, стек TCP создает буфер для чтения. Если размер оставшегося буфера слишком мал, стек TCP отправит клиенту предупреждение о размере окна.

Клиенты могут рассылают сообщения каждый из которых требует длительной обработки

клиенты отправляют сообщения на сервер в пакетах. Для каждого сообщения требуется значительное количество времени для обработки. Обработка сообщений в последовательном порядке приведет к множеству попыток TCP и будет проблематичным. В этом случае сработайте Task.Run и не беспокойтесь об исчерпании потока.

Клиенты могут отправить гораздо больше данных, чем можно обработать

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

+0

Спасибо за ваши знания TCP/IP. Я так и не думал об этом. Если мы будем затоплены, мы будем затоплены. Нам просто нужно иметь достаточно серверов для поддержки загрузки наших клиентов. –

Смежные вопросы