MVC控制器内部的异步等待

本文关键字:异步 等待 内部 控制器 MVC | 更新日期: 2023-09-27 17:58:39

我有一个返回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结果。

MVC控制器内部的异步等待

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

async不是这样工作的。正如我在博客中所描述的,async不会更改HTTP协议。

如果你想在ASP中有一个"背景"或"即发即弃"任务。NET,那么正确、可靠的方法是:

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

在ASP。NET是极其危险的。然而,如果你愿意过着危险的生活,我有一个库,你可以用ASP注册"解雇并忘记"任务。NET运行时。

您可以这样做:

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

并在一个新线程中启动您的方法。

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