在服务层使用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);
    }

在服务层使用MVC 5中的Async方法

我一直在这里阅读一些建议不要使用我想要的行为类型的问题。

那是因为它很危险。ASP。. NET决定在没有活动请求时卸载AppDomain是安全的,因此,如果您在仍有工作要做的情况下从控制器操作返回,ASP. NET就会停止运行。. NET将不会知道这个工作。

最好的解决方案是设置一个可靠的队列(例如Azure queue),并使用一个独立的后端(例如Azure WebJob)以可靠的方式处理该队列。这是正确的解决方案,但很多人就是不这么做,因为它太复杂了。

如果你的解决方案中有SQL Server或Redis数据库,请考虑Hangfire。Hangfire使用数据库作为一个可靠的队列,并与ASP一起执行它的后端。网络应用程序。

如果你想要危险的生活,至少你应该使用HostingEnvironment.QueueBackgroundWorkItem,它会通知ASP。你的应用程序在请求之外所做的工作。

方法有什么不对吗?

是的;

_myService.TestAsync正在尝试恢复已经完成的请求的请求上下文。