Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly execute an Async Method in ASP.net MVC?

How do I execute an asynchronous method from within a controller method and return an HttpStatusCodeResult(200), without the async delegate prematurely terminating its execution?

I am working on an asp.net application and one of my action my home controller takes long time to run(10-30 sec). I want to return an HttpStatusCodeResult(200) and keep running my function. The functoin need not to return anything, but still it's not really a case of fire and forget since I return a response to the server right away with HttpStatusCodeResult.

I tried using delegates, but it seems once I return the status code from the action, the delegate stops executing. Another option is to create a windows service but that would be like using a bazooka to kill a fly. I get very few requests so resources and performance is not an issue in my case. I heard ThreadPool.QueueUserWorkItem is an option, but which is most suitable for my case?

like image 553
Yehia A.Salam Avatar asked Nov 13 '22 02:11

Yehia A.Salam


1 Answers

Create a static class that manages this long-running operation. This class will be responsible for creating threads to perform the task and also provides a way to check up on the status of any ongoing operations (i.e. if it's still in progress or has finished, and if so, what the result is).

Your MVC Controller method then uses this class to do the work and present status information or the completed processed data to the user.

Something like this:

public ActionResult GetSomething(String id) {
    TaskResult result = TaskClass.GetStatus( id );
    if( result == null ) { // the task has not been run, so start it up
        TaskClass.StartNew( id );
        return new View("PleaseWait");
    } else if( !result.IsFinished ) {
        return new View("PleaseWait");
    } else {
        return View("Results", result);
    }
}

public static class TaskClass {
     private static Dictionary<String,TaskResult> _tasks;
     public static TaskResult GetStatus(String id) {
         // TODO: Make this code thread-safe
         if( _tasks.ContainsKey(id) ) return _tasks[id];
         return null;
     }
     public static void Start(String id) {
         _tasks.Add( id, new TaskResult("Working") );
         Thread thread = new Thread( SomeExpensiveOperation );
         thread.Start( id );
     }
}

At the end of SomeExpensiveOperation there would be code that marks the TaskResult as finished.

like image 110
Dai Avatar answered Dec 21 '22 00:12

Dai