在ASP.NET MVC中,当您使用已完成的操作创建异步操作时,它是否会自动异步处理?
示例:
如果我在没有声明委托的情况下有一个长时间运行的任务,那么async void会自动在后台线程中运行吗?
public void NewsAsync(string city) {
AsyncManager.OutstandingOperations.Increment();
NewsService newsService = new NewsService();
AsyncManager.Parameters["headlines"] = newsService.GetHeadlines;
AsyncManager.OutstandingOperations.Decrement();
}
或者只有在长时间运行的任务是异步任务时它才会这样做吗?
public void NewsAsync(string city) {
AsyncManager.OutstandingOperations.Increment();
NewsService newsService = new NewsService();
newsService.GetHeadlinesCompleted += (sender, e) =>
{
AsyncManager.Parameters["headlines"] = e.Value;
AsyncManager.OutstandingOperations.Decrement();
};
newsService.GetHeadlinesAsync(city);
}
所以换句话说,我不在乎void内部的方法是否是异步的,但我确实关心它是自己的void是异步的,以便释放IIS线程。
答案 0 :(得分:1)
您的第一个代码示例没有意义。 NewsAsync
必须尽快返回并将工作委托给某个后台线程。如第二个示例所示,NewsCompleted
操作会将结果传递给视图。
就这些后台线程而言,它将取决于如何实现此NewsService.GetHeadlinesCompleted
方法。异步控制器的最佳可能方案是使用I/O Completion Ports运行一些长时间运行的I / O操作(例如Web服务调用,数据库查询......)。在这种情况下,在执行请求期间没有任何线程被垄断。在其他情况下,例如尝试异步执行同步操作(这在我看来你在第一个代码示例中尝试),异步控制器的好处是非常值得怀疑的,甚至可能使事情变得更糟。
为了更深入地了解ASP.NET中的异步操作,我建议您使用following article on MSDN。它讨论了异步页面,但完全相同的概念适用于ASP.NET异步控制器,因为它们在内部实现为异步处理程序(使用IHttpAsyncHandler接口)。