【问题标题】:Can void async method be used in custom ActionResult?可以在自定义 ActionResult 中使用 void async 方法吗?
【发布时间】:2015-12-01 07:17:40
【问题描述】:

我正在尝试在我的应用程序中封装一些功能,例如,而不是在每个 POST 操作方法中编写这些代码:

var baseUrl = context.HttpContext.Request.Url.Scheme + "://" + context.HttpContext.Request.Url.Authority +
context.HttpContext.Request.ApplicationPath.TrimEnd('/') + "/signalr";
var hubConnection = new HubConnection(baseUrl);
var notification = hubConnection.CreateHubProxy(hubName: HubName);
await hubConnection.Start();
await notification.Invoke(MethodName); 
return RedirectToAction("TicketList", "Ticket")

我使用扩展方法和自定义操作结果做了这样的事情:

return RedirectToAction("TicketList", "Ticket").WithSendNotification("notificationHub", "sendNotification");

为此,我创建了一个自定义操作结果,并将逻辑放入 ExecuteResult 方法中:

public async override void ExecuteResult(ControllerContext context)
{
    var baseUrl = context.HttpContext.Request.Url.Scheme + "://" + context.HttpContext.Request.Url.Authority +
    context.HttpContext.Request.ApplicationPath.TrimEnd('/') + "/signalr";
    var hubConnection = new HubConnection(baseUrl);
    var notification = hubConnection.CreateHubProxy(hubName: HubName);
    await hubConnection.Start();
    await notification.Invoke(MethodName);
    InnerResult.ExecuteResult(context);
}

但我收到以下错误:

此时无法启动异步操作。异步 操作只能在异步处理程序中启动或 模块或页面生命周期中的某些事件期间。如果这 执行页面时发生异常,请确保该页面是 标记为 。此异常也可能表明 尝试调用通常不受支持的“async void”方法 在 ASP.NET 请求处理中。相反,异步方法 应该返回一个任务,调用者应该等待它。

现在我的问题是 void async 方法可以用于自定义操作结果吗?

更新:ASP.NET 5 有这个能力,意味着动作结果现在除了ActionResult.ExecuteResult 之外还有ActionResult.ExecuteResultAsync。现在我想知道我们如何在 MVC 5.0 中实现这种能力?

【问题讨论】:

  • 不太清楚为什么你不想仅仅重构控制器中的方法......但是这里有一个很长的问题和答案,为什么你真的不应该这样做(包括做火和 -当你试图做的时候忘记/崩溃) - stackoverflow.com/questions/17659603/…

标签: c# asp.net-mvc asynchronous asp.net-mvc-5 signalr


【解决方案1】:

我们如何在 MVC 5.0 中实现这种能力?

你不能。

正如您所注意到的,ASP.NET vNext 从头开始​​重写,并牢记async。当前版本的 ASP.NET(尤其是 MVC)有一些粗糙的地方,根本无法使用 async

【讨论】:

    【解决方案2】:

    正如Stephen 所说,我不能在MVC 5.0 中的ExecuteResult 中使用async 能力。由于我的目标是进行一点重构,我不得不使用ContinueWith

    public override void ExecuteResult(ControllerContext context)
    {
        //....
        hubConnection.Start().ContinueWith(task =>
        {
             if (task.IsCompleted)
             {
                 notification.Invoke(MethodName);
             }
        });
        InnerResult.ExecuteResult(context);
    }
    

    现在它就像一个魅力。

    【讨论】:

      猜你喜欢
      • 2021-12-10
      • 1970-01-01
      • 2011-09-19
      • 2022-11-27
      • 1970-01-01
      • 1970-01-01
      • 2013-01-28
      • 1970-01-01
      • 2013-02-01
      相关资源
      最近更新 更多