可以在自定义ActionResult中使用void async方法吗?

时间:2015-09-05 05:21:27

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

我试图在我的应用程序中封装一些功能,例如,而不是在每个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);
}

但我得到以下错误:

  

此时无法启动异步操作。异步   操作只能在异步处理程序中启动或   模块或在页面生命周期中的某些事件期间。如果这   执行页面时发生异常,确保页面为   标记为<%@ Page Async =" true" %取代。此例外也可能表示   试图调用" async void"方法,通常是不受支持的   在ASP.NET请求处理中。相反,异步方法   应该返回一个Task,调用者应该等待它。

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

更新:ASP.NET 5具有此功能,除了ActionResult.ExecuteResult之外,手段操作结果现在还有ActionResult.ExecuteResultAsync。现在我想知道如何在MVC 5.0中实现这种能力?

2 个答案:

答案 0 :(得分:1)

  

我们如何在MVC 5.0中实现此功能?

你不能。

正如您所注意到的,ASP.NET vNext从头开始重新编写,并考虑到async。当前版本的ASP.NET(特别是MVC)有一些粗略的边缘,根本不可能使用async

答案 1 :(得分:1)

正如Stephen所述,我无法在MVC 5.0中async内使用ExecuteResult能力。由于我的目标是重构,我不得不使用ContinueWith

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

现在它就像一个魅力。