Após essa pergunta, me sinto confortável ao usar operações assíncronas no ASP.NET MVC. Então, eu escrevi dois posts sobre isso:
Tenho muitos mal-entendidos em mente sobre operações assíncronas no ASP.NET MVC.
Eu sempre ouço esta frase: o aplicativo pode ser melhor dimensionado se as operações forem executadas de forma assíncrona
E também ouvi esse tipo de frase: se você tem um grande volume de tráfego, é melhor não executar suas consultas de forma assíncrona - consumir 2 threads extras para atender a uma solicitação retira recursos de outras solicitações recebidas.
Eu acho que essas duas frases são inconsistentes.
Não tenho muitas informações sobre como o threadpool funciona no ASP.NET, mas sei que o threadpool tem um tamanho limitado para threads. Portanto, a segunda frase deve estar relacionada a esse problema.
E gostaria de saber se as operações assíncronas no ASP.NET MVC usam um thread do ThreadPool no .NET 4?
Por exemplo, quando implementamos um AsyncController, como o aplicativo estrutura? Se eu receber um tráfego enorme, é uma boa ideia implementar o AsyncController?
Existe alguém por aí que possa tirar essa cortina preta diante dos meus olhos e me explicar o acordo sobre assincronia no ASP.NET MVC 3 (NET 4)?
Editar:
Eu li o documento abaixo quase centenas de vezes e compreendo o negócio principal, mas ainda tenho confusão porque há muitos comentários inconsistentes por aí.
Usando um controlador assíncrono no asp.net MVC
Editar:
Vamos supor que eu tenha uma ação do controlador como abaixo (não uma implementação do AsyncController
que):
public ViewResult Index() {
Task.Factory.StartNew(() => {
//Do an advanced looging here which takes a while
});
return View();
}
Como você vê aqui, eu aciono uma operação e a esqueço. Então, volto imediatamente sem esperar que seja concluída.
Nesse caso, isso precisa usar um thread do threadpool? Se sim, após a conclusão, o que acontece com esse segmento? Ele GC
entra e limpa logo após a conclusão?
Editar:
Para a resposta do @ Darin, aqui está um exemplo de código assíncrono que fala com o banco de dados:
public class FooController : AsyncController {
//EF 4.2 DbContext instance
MyContext _context = new MyContext();
public void IndexAsync() {
AsyncManager.OutstandingOperations.Increment(3);
Task<IEnumerable<Foo>>.Factory.StartNew(() => {
return
_context.Foos;
}).ContinueWith(t => {
AsyncManager.Parameters["foos"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
Task<IEnumerable<Bars>>.Factory.StartNew(() => {
return
_context.Bars;
}).ContinueWith(t => {
AsyncManager.Parameters["bars"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
Task<IEnumerable<FooBar>>.Factory.StartNew(() => {
return
_context.FooBars;
}).ContinueWith(t => {
AsyncManager.Parameters["foobars"] = t.Result;
AsyncManager.OutstandingOperations.Decrement();
});
}
public ViewResult IndexCompleted(
IEnumerable<Foo> foos,
IEnumerable<Bar> bars,
IEnumerable<FooBar> foobars) {
//Do the regular stuff and return
}
}