Одна из причин, по которой важно использовать асинхронное программирование, когда наше приложение полагается на внешние службы, заключается в том, чтобы разрешить ASP.NET использовать порты завершения ввода-вывода, чтобы вместо того, чтобы блокировать поток, ожидающий ответа внешней службы, ASP.NET может запарковать выполнение в порту завершения ввода-вывода и использовать поток для обслуживания другого запроса, всякий раз, когда внешняя служба отвечает, тогда ASP.NET снова получает это выполнение и возобновляет его. Таким образом, ни один поток не блокируется.
Пример асинхронного метода:
[HttpPost]
public async Task<ActionResult> Open(String key)
{
Foo foo= await _externalService.GetFoo(key);
return View(foo);
}
Но что произойдет, если мы будем использовать несколько запросов к внешним сервисам? Как с этим справляется ASP.NET?
[HttpPost]
public async Task<ActionResult> Open()
{
List<Task<Foo>> tasks = new List<Task<Foo>>();
foreach (var key in this.Request.Form.AllKeys)
tasks.Add(_externalService.GetFoo(key));
var foos = await Task.WhenAll(tasks);
Foo foo = null;
foreach (var f in foos)
{
if (foo == null && f != null)
foo = f;
else
foo.Merge(f);
}
return View(foo);
}
Он все еще использует порты завершения ввода-вывода? Или потому, что Task.WhenAll
блокирует поток?