ASP.NET MVC中的异步控制器
我有一个使用ASP.NET MVC 1开发的“博客”网站。最近的MVC版本包含AsyncController功能。这实际上需要一些额外的开发任务。但是,如何在不修改业务层的情况下重用我现有的代码。ASP.NET MVC中的异步控制器
代码的某些部分是这样的:
BlogPost post = new BlogPost();
post.GetPost(58345);
BlogComment comments = new BlogComment();
comments.GetComments(58345);
按照目前的环境下,我需要等到请求完成两个操作。使用AsyncController,我可以同时执行两个操作。但类BlogPost和BlogComment需要更改为支持异步操作,如添加EventHandlers以了解操作是否已完成等。
如何在不修改现有业务层的情况下执行异步操作。
首先,你为什么认为你需要做异步控制器?您是否遇到一些您认为异步会帮助您的性能问题?如果你真的不需要它,为什么使用Async处理应用程序变得复杂?
异步实际上是设计来处理更大规模的扩展,或者当您需要在控制器中执行非cpu绑定操作时,可能需要很长时间才能执行。
其次,我认为你对Async控制器的操作有些困惑。在大多数情况下,您不需要修改业务层,只需创建一个异步“填充程序”来包装业务层。异步并不意味着“多线程”。它仍然会为每个请求执行一个线程,并且您仍然会调用您的业务逻辑单线程(除非您编写代码来执行多线程操作)。
所有异步控制器都可以更好地利用线程池。当你有没有CPU绑定的线程时,它们可以返回到线程池,同时等待你的请求被重新激活,从而允许线程池更好地使用,而不是使用一个线程无所事事,而是等待。
如果您需要调用多个操作,请使用AsyncManager.OutstandingOperations属性来控制完成请求所需的操作数。
你可以这样做:
public class BlogController : AsyncController
{
private readonly IBlogRepository _repository;
public BlogController(IBlogRepository repository)
{
_repository = repository;
}
public void ShowAsync(int id)
{
AsyncManager.OutstandingOperations.Increment(2);
new Thread(() =>
{
AsyncManager.Parameters["post"] = _repository.GetPost(id);
AsyncManager.OutstandingOperations.Decrement();
}).Start();
new Thread(() =>
{
AsyncManager.Parameters["comments"] = _repository.GetComments(id);
AsyncManager.OutstandingOperations.Decrement();
}).Start();
}
public ActionResult ShowCompleted(Post post, IEnumerable<Comment> comments)
{
return View(new BlogViewModel
{
Post = post,
Comments = comments,
});
}
}
你应该测量你的应用程序的性能,并决定是否引入异步控制器带来的性能的任意值。
在线程池中处理你真的失败了使用的目的异步控制器。请求由线程池工作人员处理。通过对线程池中的工作进行排队,您将线程返回到线程池,只能由工作进程再次使用它。更糟糕的是,你现在正在使用两个线程。 – 2011-01-23 08:54:18
Max,你能找到解决方案吗?我在一个类似的船,并希望使用AsyncController调用我现有的业务逻辑层(BLL)方法Asynchronoulsy而不修改或添加EventHandlers到我的BLL。我将非常感谢您的回复/建议。你可以在这里看到我的问题:http://*.com/questions/5760285/changing-synchronous-operations-into-asynchronous-in-business-service-repositor – Alex 2011-04-25 07:59:10