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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With