Eu tenho trabalhado em um artigo sobre métodos de controlador assíncrono no ASP.NET MVC ( http://visualstudiomagazine.com/articles/2013/07/23/async-actions-in-aspnet-mvc-4.aspx ) e acho que Eu posso estar perdendo o objetivo.
Considere este método que escrevi, que é muito semelhante a um exemplo do artigo:
[HttpGet]
[AsyncTimeout(8000)]
[HandleError(ExceptionType = typeof(TimeoutException), View = "TimedOut")]
public async Task<ActionResult> Index(CancellationToken cancellationToken)
{
WidgetPageViewModel model = new WidgetPageViewModel()
{
toAdd = new Widget()
};
model.all = await _repo.GetAllAsync(cancellationToken);
return View(model);
}
Pelo que entendi, é assim que as coisas se desenrolam no tempo de execução:
Um thread do ASP.NET será criado para uma solicitação HTTP recebida.
Esse segmento (presumivelmente fez alguns trabalhos preliminares necessários) entra no meu método Index () acima.
A execução alcançará a palavra-chave "aguardar" e iniciará um processo de aquisição de dados em outro encadeamento.
O thread "ASP.NET" original retornará ao código que chamou meu método manipulador, com uma instância da classe Task como valor de retorno.
O código de infra-estrutura que chamou meu método manipulador continuará operando no thread "ASP.NET" original, até atingir um ponto em que precisa usar o objeto ActionResult real (por exemplo, para renderizar a página).
O chamador acessará esse objeto usando o membro Task.Result, o que fará com que ele (por exemplo, o encadeamento "ASP.NET") aguarde o encadeamento criado implicitamente na etapa 3 acima.
Não estou vendo o que isso faz em comparação com a mesma coisa sem esperar / assíncrono, exceto por duas coisas que considero insignificantes:
O segmento de chamada e o segmento de trabalho criados por aguardar podem operar em paralelo por algum período de tempo (a parte "até" do nº 5 acima). Meu palpite é que o período de tempo é bem pequeno. Quando a infraestrutura chama um método de controlador, acho que geralmente precisa do ActionResult real da chamada do controlador antes que possa fazer muito (se houver) mais.
Há alguma nova infraestrutura útil relacionada ao tempo limite e cancelamento de operações de controlador assíncrono de longa duração.
O objetivo de adicionar métodos de controlador assíncrono é supostamente liberar os threads de trabalho do ASP.NET para realmente responder às solicitações HTTP. Esses encadeamentos são um recurso finito. Infelizmente, não estou vendo como o padrão sugerido no artigo realmente serve para conservar esses threads. E, mesmo que isso ocorra, e de alguma forma descarrega o ônus de lidar com a solicitação em algum segmento que não seja do ASP.NET, o que isso faz? Os threads são capazes de lidar com uma solicitação HTTP muito diferente dos threads em geral?
Execution will reach the "await" keyword and kick off a data acquisition process on another thread
-- Não necessariamente.async
não requer outro segmento ... É uma continuação. Isso pode ser realizado reordenando as instruções no mesmo encadeamento.