在这个问题之后,它使我在使用异步时感到很舒服 所以,我写了两篇关于这个的博客文章:
对于 ASP.NET MVC 上的异步操作,我有太多的误解。
我经常听到这句话: 如果操作异步运行,应用程序可以更好地伸缩
我也经常听到这样的句子: 如果流量很大,最好不要异步执行查询——为一个请求消耗2个额外线程会占用其他传入请求的资源。
我认为这两个句子不一致。
我没有太多关于线程池在 ASP.NET 上如何工作的信息,但我知道线程池对于线程的大小是有限的。所以,第二句话必须和这个问题有关。
我想知道 ASP.NET MVC 中的异步操作是否使用.NET 4上 ThreadPool 的线程?
例如,当我们实现一个 AsyncController 时,应用程序是如何构造的?如果我得到了巨大的流量,那么实现 AsyncController 是一个好主意吗?
有没有人可以把我眼前的黑色窗帘拿开,给我解释一下 ASP.NET MVC 3(NET 4)中的异步问题?
编辑:
下面的文档我已经读过几百遍了,我理解其中的主要内容,但我仍然感到困惑,因为有太多不一致的评论。
编辑:
假设我有如下的控制器操作(但不是 AsyncController
的实现) :
public ViewResult Index() {
Task.Factory.StartNew(() => {
//Do an advanced looging here which takes a while
});
return View();
}
就像你看到的,我发动了一次行动,然后就忘了它。然后,我立即返回没有等待它被完成。
在这种情况下,必须使用线程池中的线程吗?如果是这样,在它完成之后,那个线程会发生什么?GC
是否在完成后进入并清理?
编辑:
对于@Darin 的回答,下面是一个与数据库交互的异步代码示例:
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
}
}