【问题标题】:Use Async Method at Service Layer from MVC 5?在 MVC 5 的服务层使用异步方法?
【发布时间】:2014-05-16 21:01:44
【问题描述】:

我正在开发一个 ASP.NET MVC 5 应用程序。我一直在阅读一些问题here,建议不要使用我想要的行为类型。

我想要达到的高水平 -

MVC 控制器 - 在服务层调用方法,然后继续控制器中的下一行代码,因为不需要返回任何内容。

服务层中的方法 - 我想调用一些具有异步方法的外部 Web 服务,所以我希望这些方法在运行时运行,然后在它们返回时将数据写入数据库。

这样的事情可以实现还是不是最好的方法?

为了模拟这个并测试我在控制器上的原理:

    [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 秒,然后我可以检查数据库并添加值测试。但是,这不起作用 - 在 UI 上,点击按钮后,页面转到摘要视图,等待 Task.Delay 断点被命中,但下一行永远不会执行。这种方法有什么不正确的吗? 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);
    }

【问题讨论】:

    标签: c# .net asp.net-mvc asynchronous async-await


    【解决方案1】:

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

    那是因为它很危险。 ASP.NET 决定在没有活动请求时卸载您的 AppDomain 是安全的,因此如果您在仍有工作要做的情况下从控制器操作返回,ASP.NET 将不会意识到该工作。

    最好的解决方案是设置一个可靠的队列(例如 Azure 队列)和一个单独的后端(例如 Azure WebJob),以可靠的方式处理该队列。这是正确的解决方案,但很多人不会这样做,因为它很复杂。

    如果您的解决方案中有 SQL Server 或 Redis 数据库,请考虑使用Hangfire。 Hangfire 将数据库用作可靠队列,并与您的 ASP.NET 应用程序一起执行其后端。

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

    这种方法有什么不正确的地方吗?

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

    【讨论】:

    • 简要了解了 Hangfire - 我正在使用 MongoDB 作为后端数据库,但不确定它是否可以使用。
    • 不增加队列的复杂性并且不在 .NET 4.5.2 上 - 应用程序是 4.5 - 有没有办法可以调用此服务层并创建一个新线程来完成工作- 因为不需要向用户返回某些东西 - 我只希望新线程完成工作并将数据从 Web 服务持久保存到数据库
    • 如果您不想升级到 4.5.2,可以使用我的AspNetBackgroundTasks library
    • 感谢 Stephen - 将研究如何使用该库 - 使用 Web API 控制器在这里会有什么不同吗?还是问题的根源仍然存在?
    猜你喜欢
    • 1970-01-01
    • 2014-05-29
    • 2022-12-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多