Async-Await против ThreadPool против MultiThreading на высокопроизводительных сокетах (решения C10k?)

Я действительно смущен async-await s, pool с и thread s. Основная проблема начинается с этого вопроса: "Что я могу сделать, когда мне приходится обрабатывать ввод / вывод 10k сокетов?" (иначе проблема C10k).

  • Сначала я попытался создать собственную архитектуру пула с потоками, использующими один основной Queue и несколько Thread s для обработки всех входящих данных. Это был большой опыт понимания thread-safety а также multi-threading но thread это перебор с async-await Настоящее время.
  • Позже я реализовал простую архитектуру с async-await но я не могу понять, почему "ключевые слова async и await не создают дополнительных потоков". ( из MSDN)? Я думаю, что должно быть thread чтобы сделать работу, как BackgroundWorker.
  • Наконец, я реализовал другую архитектуру с ThreadPool и это похоже на мой первый пользовательский пул.

Теперь, я думаю, что должен быть кто-то еще со мной, кто запутался в обращении с C10k. Мой проект - это выделенный (центральный) сервер для моего игрового проекта, который является хабом / лобби-сервером, таким как лобби MCSG или серверы матчей COD. Я буду выполнять операции входа в систему, выполнения / запросы команд игрового сервера и обслуживание информации (например, версию, патч).

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

(Также да, обработка соединения 1k-10k-100k в зависимости от аппаратного обеспечения сервера, но это общий вопрос)


Ключевой момент: выбор между библиотекой параллельных задач и ThreadPool (блог MSDN)


[ДОПОЛНИТЕЛЬНО] Хорошие (базовые) вещи для чтения, кто хочет понять, о чем мы говорим:

  1. Потоки
  2. Async, Await
  3. ThreadPool
  4. BackgroundWorker

2 ответа

Решение

async/await примерно аналогичен подходу "Обслуживать много клиентов с каждым потоком и использовать асинхронный ввод-вывод и уведомление о завершении" в вашей статье.

В то время как async а также await сами по себе не вызывают никаких дополнительных потоков, они будут использовать потоки пула потоков, если async метод возобновляется в контексте пула потоков. Обратите внимание, что async взаимодействие с ThreadPool высоко оптимизирован; очень сомнительно, что вы можете использовать Thread или же ThreadPool чтобы получить ту же производительность (при разумных сроках разработки).

Если вы можете, я бы порекомендовал использовать существующий протокол - например, SignalR. Это значительно упростит ваш код, поскольку существует множество (много) ловушек при написании собственного протокола TCP/IP. SignalR может быть размещен самостоятельно или размещен на ASP.NET.

Нет. Если мы используем шаблон асинхронного программирования, который был введен в.NET в 4.5, в большинстве случаев нам не нужно создавать ручной поток. Компилятор выполняет сложную работу, которую делал разработчик. Создание новой темы стоит дорого, это требует времени. Если нам не нужно управлять потоком, то "Асинхронный шаблон на основе задач (TAP)" и "Параллельная библиотека задач (TPL)" достаточно хороши для асинхронного и параллельного программирования. TAP и TPL использует Task. В общем случае Task использует поток из ThreadPool(Пул потоков - это набор потоков, уже созданных и поддерживаемых.NET Framework. Если мы используем Task, в большинстве случаев нам не нужно использовать пул потоков напрямую. Поток может сделать гораздо больше полезные вещи. Вы можете узнать больше о Thread Pooling

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

Await специально разработан, чтобы справляться с чем-то, что требует времени, чаще всего это запрос ввода-вывода. Что традиционно было сделано с обратным вызовом, когда запрос ввода / вывода был выполнен. Написание кода, использующего эти обратные вызовы, довольно сложно, а ожидание значительно упрощает его. Await позаботится о том, чтобы справиться с задержкой, иначе он не сделает ничего, что делает поток. Выражение await, которое находится справа от ключевого слова await, - это то, что выполняет работу. Вы можете использовать Async с любым методом, который возвращает задачу. Методы XxxxAsync() - это просто предварительно подготовленные методы в.NET Framework для обычных операций, которые требуют времени. Как и загрузка данных с веб-сервера.

Я бы порекомендовал вам прочитать Асинхронное программирование с Async и Await

Другие вопросы по тегам