In an Asp.Net MVC application if an Asynchronous Controller's Session behavior is Read only, its Action method is also Asynchronous and within it we create a Task Thread that does some long running stuff, example:
[SessionState(SessionStateBehavior.ReadOnly)]
public class UploadController : AsyncController
{
public void UploadFilesAsync(IEnumerable<HttpPostedFileBase> assetFiles,
string filesMetaInfo)
{
var postedFiles = assetFiles;
var fInfo = filesMetaInfo;
AsyncManager.OutstandingOperations.Increment();
Task.Factory.StartNew(
() => ProcessUploadedFile(postedFiles, fInfo),
CancellationToken.None, TaskCreationOptions.DenyChildAttach,
TaskScheduler.FromCurrentSynchronizationContext());
}
public ActionResult UploadFilesCompleted(object result)
{
return Json(new
{
status = "OK"
}, "text/plain");
}
private void ProcessUploadedFile(IEnumerable<HttpPostedFileBase>
assetFiles, string filesInfo)
{
// Do some long running stuff here like file processing.
// ......................
// ..................................
AsyncManager.Parameters["result"] = "success"
AsyncManager.OutstandingOperations.Decrement();
}
}
Two questions now:
Will this Controller Action method UploadFilesAsync(), release this Controller for other Requests once the inside Task thread work completes fully or be available to other Requests right after when the Task just starts executing?
Also what will happen if I make this UploadFilesAsync() method behave in a synchronous manner by applying "Synchronized" attribute on it? example:
[MethodImpl(MethodImplOptions.Synchronized)]
By "release this controller" I'm assuming you mean release the ASP.NET threadpool thread currently occupied with processing your message. If so, the answer is the latter. It will release the current thread immediately without waiting for the inner task executed to complete.
MethodImplOptions.Synchronizeddoes not make the method run synchronously. It merely is like wrapping your whole method executing withlock (this). This would mean the that multiple callers won't be able to use the same instance of yourController, but that doesn't happen anyway, as a newControlleris spun up for every request made. That means it will make no difference whatsoever.As a side note - You should not be using
Task.Factory.StartNewnorTask.Runinside ASP.NET, because any work offloaded to that threadpool thread will not be registered with IIS, which means your thread could be abnormally aborted due to IIS recycling. Instead, look intoHostingEnvironment.QueueBackgroundWorkItemif you're using .NET 4.5.2, or look into Stephan Clearys AspNetBackgroundTasks