【问题标题】:async await inside MVC controllerMVC 控制器中的异步等待
【发布时间】:2014-04-16 19:59:12
【问题描述】:

我有一个返回 JSON 结果的控制器操作方法。 在这个控制器动作中,我想做 asyc 并等待一个长时间运行的操作,而不是等待 JSON 结果返回到浏览器。

我有以下示例代码 -

`public JsonResult GetAjaxResultContent(string id)
        {
            List<TreeViewItemModel> items = Test();
            //use the below long running method to do async and await operation.
            CallLongRunningMethod();

            //i want this to be returned below and not wait for long running operation to complete

            return Json(items, JsonRequestBehavior.AllowGet);
        }


private static async void CallLongRunningMethod()
        {

            string result = await LongRunningMethodAsync("World");

        }

        private static Task<string> LongRunningMethodAsync(string message)
        {
            return Task.Run<string>(() => LongRunningMethod(message));
        }

        private static string LongRunningMethod(string message)
        {
            for (long i = 1; i < 10000000000; i++)
            {

            }
            return "Hello " + message;
        }

`

但是,控制器操作会一直等待,直到它完成长时间运行的方法,然后返回 json 结果。

【问题讨论】:

  • ...所以不要等待它?只需启动一项任务...
  • @SimonWhitehead 不负责任的回答。根据 Nisd 的描述,这可能会导致问题。如果客户端 javascript 发送另一个请求来启动长期存在的过程,那就更好了。 IIS
  • @Aron 这不是一个答案.. 这是一个评论 :) 我知道这些陷阱 - 但是,问题是它是什么,我怀疑这是“关键任务" 到 OP 的业务。

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


【解决方案1】:

在这个控制器动作中,我想做 asyc 并等待一个长时间运行的操作,而不是等待 JSON 结果返回到浏览器。

async 不是这样工作的。正如我在博客中描述的那样,async does not change the HTTP protocol

如果您想要在 ASP.NET 中执行“后台”或“即发即弃”任务,那么正确、可靠的方法是:

  1. 将工作发布到可靠队列。例如,Azure 队列或 MSMQ。
  2. 有一个独立的进程从队列中检索工作并执行它。例如,Azure webrole、Azure Web Worker 或 Win32 服务。
  3. 将结果通知浏览器。例如,SignalR 或电子邮件。

在 ASP.NET 中启动一个单独的线程或任务是极其危险的。但是,如果您愿意冒险生活,我有一个library you can use to register "fire and forget" tasks with the ASP.NET runtime

【讨论】:

    【解决方案2】:

    你可以这样做:

    new System.Threading.Thread(() => CallLongRunningMethod()).Start();
    

    然后在一个新线程中开始你的方法。

    但不建议在 Web 服务器上启动新线程,因为应用程序池可能随时在您不知情的情况下关闭,并使您的应用程序处于无效状态。

    【讨论】:

    • IIS 可以配置为从 Windows 8/Windows 2012 开始像人们天真期望的那样工作。但是它并不简单,我不会推荐它。如果你想运行长时间运行的进程,你应该使用 Windows 服务。
    猜你喜欢
    • 2012-12-07
    • 2023-03-08
    • 2012-10-14
    • 1970-01-01
    • 2018-03-12
    • 2014-05-15
    • 2017-10-08
    • 1970-01-01
    相关资源
    最近更新 更多