【问题标题】:Any issues with always using ASP.NET MVC AsyncController instead of Controller?总是使用 ASP.NET MVC AsyncController 而不是 Controller 有什么问题吗?
【发布时间】:2012-07-12 06:19:39
【问题描述】:

我们有一系列 ASP.NET MVC 控制器,它们都继承自一个基本控制器(继承自 Controller 类)。我们现在正在考虑创建一些异步操作,并且想知道如果我们只是将基本控制器更改为从 AsyncController 继承而不是 Controller(这意味着我们所有的控制器都将从 AsyncController 继承),是否会遇到任何麻烦。

【问题讨论】:

  • 这里有一篇关于异步控制器的非常好的博客文章blog.stevensanderson.com/2008/04/05/…
  • @Miau:那篇文章看起来很老了;作者正在滚动他自己的 AsyncController 类。
  • 使用 MVC 4,其中 Controller 支持异步操作并且没有实现 Async 控制器类。请参阅下面的 MVC 异步教程和我的答案。 asp.net/mvc/tutorials/mvc-4/…

标签: asp.net-mvc


【解决方案1】:

杰斯,

在我看来,你不会造成任何伤害,因为只有当你遵循以下约定时才会调用异步功能:

public class PortalController : AsyncController
{
    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);
    }

    public ActionResult NewsCompleted(string[] headlines)
    {
        return View("News", new ViewStringModel
        {
            NewsHeadlines = headlines
        });
    }
}

约定是在命名中添加 News*Async* 和 News*Completed* 部分。

见:

async controllers in asp.net mvc 2

请注意,控制器类现在派生自 AsyncController 而不是 Controller。此外,News 操作方法已拆分为名为 NewsAsync 和 NewsCompleted 的方法,它们类似于异步页面中的 Begin 和 End 方法。从逻辑上讲,控制器仍然公开了一个名为 News 的操作方法。但在物理上,该方法的实现已经使用整个 .NET 框架中使用的异步模式的变体进行了分解。

如果您不更改继​​承的控制器代码中的任何内容,则不会启动异步活动。然而,正如罗伯特在上面(或下面可能:-))所说,你可以根据需要装饰动作以保持意图清晰,但我个人认为约定应该清楚地表明这一点。

当然值得讨论。

【讨论】:

  • 感谢 jim - 我是否正确地说使用 Controller 而不是 AsyncController 没有具体的好处?
  • Jess - 除了 Robert 之前提到的(重新明确目的)之外,我认为拥有 asynccontroller 基础可以获得更多好处。正如我们所知,您不必“必须”使用这些功能。老实说,我在我的基本控制器中使用它已经有一段时间了,并且只有一个使用它的实例。但是这种单一用途的定义如此明确,以至于其他地方发生了什么并不神秘。事实上,由于我继承的控制器只显示 MyController : BaseController,没有真正的线索表明我使用的控制器与以前有任何不同......
  • 哦!不知何故 AsyncManager.OutstandingOperations.Increment/Decrement 很重要,没有它异步行为就不起作用。检查这个stackoverflow.com/a/9805030/1182982
【解决方案2】:

MVC 4 没有异步控制器 - 查看源代码:

    namespace System.Web.Mvc
{
    // Controller now supports asynchronous operations.
    // This class only exists 
    // a) for backwards compat for callers that derive from it,
    // b) ActionMethodSelector can detect it to bind to ActionAsync/ActionCompleted patterns. 
    public abstract class AsyncController : Controller
    {
    }
}

看我的教程Using Asynchronous Methods in ASP.NET MVC 4

【讨论】:

    【解决方案3】:

    如果您在 Action 方法中设置断点并观察调用堆栈(启用显示外部代码),您将看到调用驻留在 AsyncController 中的同步操作与标准控制器中的同步操作需要几个额外的步骤。即 AsyncControllerActionInvoker 调用以 BeginInvokeSynchronousActionMethod 结尾的 Begin/End 样式方法。我不知道这些额外调用会带来多少开销,但在你盲目地从 AsyncController 扩展所有控制器之前,即使不存在异步操作,也需要注意这一点。

    【讨论】:

      【解决方案4】:

      你应该没问题,因为 AsyncController 已经继承自 Controller

      See here for more information

      该页面上的注释对于确定您是否通过从 AsyncController 继承来做正确的事情非常有用,并提供了一个很好的指导来让您保持正轨。

      【讨论】:

        【解决方案5】:

        异步控制器的使用取决于您是否要等待任何特定任务或步骤完成,然后再继续下一个任务。这个问题类似于在你的薪水进入你的支票账户之前从亚马逊购买东西。

        对于典型的 Web 应用程序,我认为这是不可取的。 Web 服务器已经是非常并行的,因此唯一的优势就是加快对用户的响应速度。对于许多操作来说,这种好处可以忽略不计。

        我会在后台为长时间运行的进程保留异步控制器,在后台等待任务完成再将网页返回给用户控制是不切实际的。

        注意:如果您有一个 .NET 反汇编程序(或 ASP.NET MVC source)的副本,您可以打开 AsyncController 类并查看代码。这应该让您很好地了解是否可以将AsyncController 用作普通的Controller

        我在下面链接到的文章是这样说的:“从 AsyncController 派生的控制器使 ASP.NET 能够处理异步请求,并且它们仍然可以为同步操作方法提供服务。”

        http://msdn.microsoft.com/en-us/library/ee728598.aspx

        【讨论】:

        • robert - 我认为 OP 指的是从异步控制器本身继承,而不是将所有调用实现为异步。我以前可能是错的 :)
        • @jim:啊,我明白了。从AsyncController继承,然后同步使用?如果需要,为什么不直接使用普通控制器并将其切换到 AsyncController 呢?从“明确你的意图”的角度来看,这肯定会更好。
        • 罗伯特,我想也许 Jess 可能打算同步使用一些动作,而其他一些动作是异步的。但我明白你的意思是从一开始就明确意图......
        • @jim:再次阅读这个问题,看起来这是关于在自定义基类中保留一些功能。我不太了解ControllerAsyncController 的内部结构,不知道Jess 的策略是否有效;从理论上讲,您应该能够从 AsyncController 继承并以通常的方式使用 Controller 的功能(假设 AsyncController 中没有 Controller 的方法)。
        • @jim - 你正确地解释了我的问题......本质上 - 如果 AsyncController 只是一个具有一些附加功能的常规控制器,为什么不一直使用 AsyncController (但处理 99%所有动作同步)?我想确保这样做没有任何缺点。
        猜你喜欢
        • 2014-12-30
        • 1970-01-01
        • 2012-11-23
        • 2015-04-07
        • 2013-12-07
        • 1970-01-01
        • 2013-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多