1

I have a .NET MVC app deployed in IIS. On getting a request, I am supposed to start a job (which might take hours to finish). So, I was creating a thread inside my controller layer and letting the thread do the work asynchronously, and the request thread was returning an id to the client. On debugging I found that the thread that I created inside controller layer was also ending as soon as the request thread is over(that is the http request cycle is over and reponse is returned to the client). I tried creating thread using normal Thread library and also system threadpool. All the threads were foreground. Still I am not able to figure out why should the newly created thread end as soon as the request thread exits. My hunch is that for each new request IIS could be creating a light weight process. Since this thread was created from a process, it should also exit when the process exits(in this case the process should exit on http request finish), which is the only plausible explanation. Am I correct here? any leads would be appreciated.

  • Possible duplicate of [Why are IIS threads so precious as compared to regular CLR threads?](https://stackoverflow.com/questions/12304691/why-are-iis-threads-so-precious-as-compared-to-regular-clr-threads) – Lex Li Dec 21 '18 at 15:04
  • Never put such jobs in an ASP.NET web app. Move it to another process such as Windows service. https://stackoverflow.com/questions/5553001/how-should-i-perform-a-long-running-task-in-asp-net-4 – Lex Li Dec 21 '18 at 15:06
  • There is no use of "lighweight processes" or such things. Requests run on the thread pool and your custom threads should behave like they always do. The reason why the thread exited has nothing to do with IIS. It is a bug in your code. Set the debugger to break on any exception. Maybe your thread crashed. – usr Dec 21 '18 at 15:25

1 Answers1

1

A request has an explicit timeout that is defined by the server. I forget what the default is, but this explicit timeout would definitely be way shorter than hours. See this post for more information: How to increase executionTimeout for a long-running query?

<system.web>
   <httpRuntime  executionTimeout = "SOME LARGE VALUE" />

That would increase the timeout for ALL pages in the app, so using the location element to define it for one path is ideal:

<location path="Pathtolongrunningtask">
    <system.web>
       <httpRuntime  executionTimeout = "SOME LARGE VALUE" />

The maxRequestLength element also increases the maximum size of data can be downloaded too, so updating that setting if this is a large file that gets downloaded is also important.

What we've done with some success in the past is load the page and initiate the request via an AJAX call, and wait for that call to finish. One common problem with that is for some reason, the user's session would die and this would prevent the process from finishing, so we needed to add a keep alive mechanism that while it was waiting for a response, the session wouldn't die and log the user out.

Generally there can be problems with doing this within the HTTP lifecycle - if you can utilize a windows task or Azure web worker or something outside of the HTTP lifecycle, that would work better.

Brian Mains
  • 50,520
  • 35
  • 148
  • 257