我试图在我的应用程序中封装一些功能,例如,而不是在每个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中实现这种能力?
答案 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);
}
现在它就像一个魅力。