提出这个问题后,在ASP.NET MVC中使用异步操作时,我感到很舒服。因此,我就此写了两篇博客文章:
我对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
}
}