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

本文关键字:async void 方法 自定义 ActionResult | 更新日期: 2023-09-27 18:11:13

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

我已经使用扩展方法和自定义actionresult:

做了这样的东西
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。ExecuteResultAsync除ActionResult.ExecuteResult外。现在我想知道我们如何在MVC 5.0中实现这个功能?

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

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

你不能。

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

正如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);
}