异步等待MVC控制器内部

时间:2014-04-16 10:14:53

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

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

2 个答案:

答案 0 :(得分:2)

  

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

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

如果你想要&#34;背景&#34;或者&#34;一劳永逸的&#34;在ASP.NET中的任务,那么正确,可靠的方法是:

  1. 将作品发布到可靠的队列中。例如,Azure队列或MSMQ。
  2. 有一个独立的进程从队列中检索工作并执行它。例如,Azure webrole,Azure Web worker或Win32服务。
  3. 通知浏览器结果。例如,SignalR或电子邮件。
  4. 在ASP.NET中启动单独的线程或任务非常危险。但是,如果你愿意生活危险,我有library you can use to register "fire and forget" tasks with the ASP.NET runtime

答案 1 :(得分:0)

你可以这样做:

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

在新线程中启动你的方法。

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