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以了解操作是否已完成等。

如何在不修改现有业务层的情况下执行异步操作。

+0

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

首先,你为什么认为你需要做异步控制器?您是否遇到一些您认为异步会帮助您的性能问题?如果你真的不需要它,为什么使用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, 
     }); 
    } 
} 

你应该测量你的应用程序的性能,并决定是否引入异步控制器带来的性能的任意值。

+2

在线程池中处理你真的失败了使用的目的异步控制器。请求由线程池工作人员处理。通过对线程池中的工作进行排队,您将线程返回到线程池,只能由工作进程再次使用它。更糟糕的是,你现在正在使用两个线程。 – 2011-01-23 08:54:18