1

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:

  1. 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?

  2. 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)]

Faisal Mq
  • 5,036
  • 4
  • 35
  • 39

1 Answers1

2

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?

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.

Also what will happen if I make this UploadFilesAsync() method behave in a synchronous manner by applying "Synchronized" attribute on it?

MethodImplOptions.Synchronized does not make the method run synchronously. It merely is like wrapping your whole method executing with lock (this). This would mean the that multiple callers won't be able to use the same instance of your Controller, but that doesn't happen anyway, as a new Controller is 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.StartNew nor Task.Run inside 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 into HostingEnvironment.QueueBackgroundWorkItem if you're using .NET 4.5.2, or look into Stephan Clearys AspNetBackgroundTasks

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • Your link of Stephen Cleary himself mentions that this is dangerous and unreliable solution. Means the IIS can still recycle it. He is also suggesting to better use .Net 4.5.2 like you did above. – Faisal Mq Apr 27 '15 at 08:16
  • 1
    @FaisalMq That is why I referenced it :). It is a great article. – Yuval Itzchakov Apr 27 '15 at 08:22
  • Hi Yuval, I downloaded 4.5.2 Runtime and developer pack and used QueueBackgroundWorkItem. One concern I have seen in an MSDN blog that "The AppDomain shutdown can only be delayed 90 seconds. If you have so many items queued that they can’t be completed in 90 seconds, the ASP.NET runtime will unload the AppDomain without waiting for the work items to finish. " What does that mean? – Faisal Mq Apr 27 '15 at 10:19
  • @FaisalMq That means that when a recycle wants to kick in, the queue that registers all the work has 90 seconds to complete everything. If it doesn't complete, it will shut down the AppDomain anyway, and your work will be lost. 90 seconds should be plenty of time to finish whatever is going on. – Yuval Itzchakov Apr 27 '15 at 10:20
  • Actually I have a weird scenario in which I will further upload the web server uploaded file stream up to an Azure Server and so it might take more than 90 seconds within the Queued Work Item background task. Does that mean I have a chance that this second Azure uploading task might not be able to complete and IIS recycle will proceed after 90 secs of delay? – Faisal Mq Apr 27 '15 at 10:42
  • @Faisal That is possible. If you don't care about IIS recycling, you can disable it or extend the time in which it happens. Also, you can look for a persistent solution such Azure Queues. – Yuval Itzchakov Apr 27 '15 at 10:53