Использование асинхронности в многопоточном серверном приложении
Cоздаётся многопоточное серверное приложение. Существует цикл в основном потоке, который принимает входящие соединения. Далее каждое соединение должно обрабатывается в отдельном потоке методом Process, который содержит множество вызовов асинхронных методов, читающих или записывающих данные в Stream, представляющий соединение. Имеет ли смысл делать метод Process асинхронным и запускать обработку каждого соединения отдельной задачей? Как минимум это удобно в плане написания кода, ведь вместо использования GetAwaiter().GetResult() можно писать просто await. Так же могут быть задержки связанные с ожиданием получения данных от клиента, которые не будут блокировать поток и он может обрабатывать другие соединения.
Однако, все вызовы асинхронного метода Process, обрабатывающего соединения, будут выполняться в одном потоке (при условии что до начала цикла приёма входящих соединений существовал 1 поток), ведь задача запускается с параметрами по-умолчанию, то есть созданные задачи не будут порождать новые потоки. Верно ли это и как исправить ситуацию?
Ответы (1 шт):
Однако, все вызовы асинхронного метода Process, обрабатывающего соединения, будут выполняться в одном потоке (при условии что до начала цикла приёма входящих соединений существовал 1 поток), ведь задача запускается с параметрами по-умолчанию, то есть созданные задачи не будут порождать новые потоки. Верно ли это и как исправить ситуацию?
Глупость полная. Вот типичный цикл приёма соединений:
while(…) {
var connection = await listener.Accept();
var task = Task.Run(() => Process(connection, token));
someTasksContainer.Add(task);
}
await someTasksContainer.WaitForAllTasks();
Задачи, создаваемые через Task.Run, могут выполняться в любом потоке пула.