ASP.NET MVC中的异步控制器

时间:2011-01-23 08:24:21

标签: asp.net-mvc multithreading asynchronous

我有一个使用ASP.NET MVC开发的“博客”网站1.最新版本的MVC包含AsyncController功能。这实际上需要一些额外的开发任务。但是,如何在不修改业务层的情况下重用现有代码。

代码的某些部分如下:

BlogPost post = new BlogPost();
post.GetPost(58345);

BlogComment comments = new BlogComment();
comments.GetComments(58345);

根据当前环境,我需要等到请求完成两个操作。使用AsyncController,我可以同时执行两个操作。但需要更改BlogPost和BlogComment类以支持异步操作,例如添加EventHandler以了解操作是否已完成等等。

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

2 个答案:

答案 0 :(得分:3)

你可以这样做:

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,
        });
    }  
}

您应该衡量应用程序的性能,并决定引入异步控制器是否会为性能带来任何价值。

答案 1 :(得分:2)

首先,您认为为什么需要执行异步控制器?您是否遇到了一些您认为Async会帮助您的性能问题?如果您真的不需要,为什么使用异步处理使应用程序复杂化?

异步实际上是为了处理更大规模的扩展,或者当您需要在控制器中执行可能需要很长时间才能执行的非cpu绑定操作时。

其次,我认为您对Async控制器的运行方式有点困惑。在大多数情况下,您无需修改​​业务层,只需创建一个异步“shim”来包装业务层。异步并不意味着“多线程”。它仍然会为每个请求执行一个线程,并且您仍然会将业务逻辑称为单线程(除非您编写代码来执行多线程的事务)。

所有异步控制器都允许更好地利用线程池。当你拥有不受CPU限制的线程时,它们可以在等待你的请求被重新激活时返回到线程池,从而允许更好地使用线程池,而不是使用除了等待之外什么都不做的线程。 / p>

如果需要调用多个操作,可以使用AsyncManager.OutstandingOperations属性来控制完成请求必须完成的操作数。