1

I have a controller action method that returns JSON result. In this controller action, i want to do asyc and await for a long running operation without waiting for the JSON result to return to the browser.

I have below sample code -

`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;
        }

`

However, the controller action waits untill it finishes the long running method and then returns the json result.

3
  • 1
    ...so don't await it? Just fire off a task... Commented Apr 16, 2014 at 10:26
  • 1
    @SimonWhitehead not responsible answer. This is likely to cause problems down the line as per Nisd described. It would be MUCH better if the client javascript sent another request to kick off the long lived process. IIS <= 7.5 REQUIRES a request for every thread it is running, and will terminate Tasks without requests without warning. Commented Apr 16, 2014 at 11:00
  • @Aron It wasn't an answer.. it was a comment :) I am aware of the pitfalls - but, the question being what it is, I had doubts that this was "mission-critical" to the OP's business. Commented Apr 16, 2014 at 11:02

2 Answers 2

2

In this controller action, i want to do asyc and await for a long running operation without waiting for the JSON result to return to the browser.

That's not how async works. As I describe on my blog, async does not change the HTTP protocol.

If you want a "background" or "fire-and-forget" task in ASP.NET, then the proper, reliable way to do it is:

  1. Post the work to a reliable queue. E.g., Azure queue or MSMQ.
  2. Have an independent process that retrieves work from the queue and executes it. E.g., Azure webrole, Azure web worker, or Win32 service.
  3. Notify the browser of the results. E.g., SignalR or email.

Starting a separate thread or task in ASP.NET is extremely dangerous. However, if you are willing to live dangerously, I have a library you can use to register "fire and forget" tasks with the ASP.NET runtime.

Sign up to request clarification or add additional context in comments.

Comments

0

You could do like this:

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

And start your method in a new thread.

But starting new threads on a web server is not recommend, because the application pool could shutdown at anytime without you knowing, and put your application in a invalid state.

1 Comment

IIS CAN be configured to work as one naively expects as of Windows 8/Windows 2012. However its not simple and I would not recommend it. You should use a Windows Service if you want to run long running processes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.