Я работаю на сервере tcp, который выглядит примерно так, используя синхронный apis и пул потоков:
TcpListener listener;
void Serve(){
while(true){
var client = listener.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(this.HandleConnection, client);
//Or alternatively new Thread(HandleConnection).Start(client)
}
}
Предполагая, что моя цель состоит в том, чтобы обрабатывать как можно больше параллельных подключений при минимальном использовании ресурсов, похоже, что это будет быстро ограничено количеством доступных потоков. Я подозреваю, что с помощью неблокирующей задачи apis я смогу обрабатывать гораздо больше с меньшим количеством ресурсов.
Мое первое впечатление - это что-то вроде:
async Task Serve(){
while(true){
var client = await listener.AcceptTcpClientAsync();
HandleConnectionAsync(client); //fire and forget?
}
}
Но мне кажется, что это может вызвать узкие места. Возможно, HandleConnectionAsync займет необычно долгое время, чтобы нажать на первый вызов и остановит основной цикл принятия. Будет ли это использовать только один поток когда-либо, или будет ли время выполнения волшебным образом работать над несколькими потоками по своему усмотрению?
Есть ли способ объединить эти два подхода, чтобы мой сервер точно использовал количество потоков, необходимое для количества активных задач, но чтобы он не блокировал потоки без необходимости в операциях ввода-вывода?
Есть ли идиоматический способ максимизации пропускной способности в такой ситуации?