在服务层使用MVC 5中的Async方法
本文关键字:中的 Async 方法 MVC 服务 | 更新日期: 2023-09-27 18:03:34
我正在开发一个ASP。. NET MVC 5应用程序。我一直在这里读一些问题,建议不要使用我想要的行为类型。
我想要达到的高水平-
MVC控制器-调用服务层的方法,然后继续控制器中的下一行代码,因为不需要返回任何东西。
方法在服务层-我想调用一些外部的Web服务,有Async方法,所以我希望这些运行off,然后写入数据到DB时,他们返回。
这样的事情是可以实现的还是不是最好的方法?
为了模拟并测试这个原理,我在控制器上设置了以下内容:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TestAsync()
{
_myService.TestAsync();
return RedirectToAction("Summary");
}
在_myService中,方法如下:
public async Task TestAsync()
{
await Task.Delay(10000);
var test = "Testing";
_testRepository.Add(test);
}
我希望这个TestAsync方法将等待10秒,然后我可以检查DB和值Testing将被添加。然而,这是不工作-在UI上点击按钮后,页面转到摘要视图和等待任务。延迟断点被击中,但下一行永远不会执行。这种方法有什么不对吗?TestAsync方法应该看起来像这样:
public void TestAsync()
{
//Call another private async method here in the class that does the task delay
//which would be similar to calling the actual Async External Web Service methods
var test = "Testing";
_testRepository.Add(test);
}
我一直在这里阅读一些建议不要使用我想要的行为类型的问题。
那是因为它很危险。ASP。. NET决定在没有活动请求时卸载AppDomain是安全的,因此,如果您在仍有工作要做的情况下从控制器操作返回,ASP. NET就会停止运行。. NET将不会知道这个工作。
最好的解决方案是设置一个可靠的队列(例如Azure queue),并使用一个独立的后端(例如Azure WebJob)以可靠的方式处理该队列。这是正确的解决方案,但很多人就是不这么做,因为它太复杂了。
如果你的解决方案中有SQL Server或Redis数据库,请考虑Hangfire。Hangfire使用数据库作为一个可靠的队列,并与ASP一起执行它的后端。网络应用程序。
如果你想要危险的生活,至少你应该使用HostingEnvironment.QueueBackgroundWorkItem
,它会通知ASP。你的应用程序在请求之外所做的工作。
方法有什么不对吗?
是的;
_myService.TestAsync
正在尝试恢复已经完成的请求的请求上下文。