Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use threads to carry out long-running jobs on IIS?

In an ASP.Net application, the user clicks a button on the webpage and this then instantiates an object on the server through the event handler and calls a method on the object. The method goes off to an external system to do stuff and this could take a while. So, what I would like to do is run that method call in another thread so I can return control to the user with "Your request has been submitted". I am reasonably happy to do this as fire-and-forget, though it would be even nicer if the user could keep polling the object for status.

What I don't know is if IIS allows my thread to keep running, even if the user session expires. Imagine, the user fires the event and we instantiate the object on the server and fire the method in a new thread. The user is happy with the "Your request has been submitted" message and closes his browser. Eventually, this users session will time out on IIS, but the thread may still be running, doing work. Will IIS allow the thread to keep running or will it kill it and dispose of the object once the user session expires?

EDIT: From the answers and comments, I understand that the best way to do this is to move the long-running processing outside of IIS. Apart from everything else, this deals with the appdomain recycling problem. In practice, I need to get version 1 off the ground in limited time and has to work inside an existing framework, so would like to avoid the service layer, hence the desire to just fire off the thread inside IIS. In practice, "long running" here will only be a few minutes and the concurrency on the website will be low so it should be okay. But, next version definitely will need splitting into a separate service layer.

like image 858
flytzen Avatar asked Feb 11 '09 13:02

flytzen


People also ask

What are IIS threads?

What is the IIS thread pool. The IIS thread pool maintains the threads designed to rapidly dequeue requests from the application pool queue, and process them inside the IIS worker process. Like all thread pools, it limits how many threads can be created and how fast they are created.

How do I increase the thread pool size in IIS?

To increase the value for the Threads Per Processor Limit follow these steps:In the Connections pane, select the web server, click to select Features View, and then double-click the ASP feature. Click Start, point to All Programs, click Administrative Tools, and then click Internet Information Services (IIS) Manager.

How do I view threads in IIS?

To see how many threads are possible in an IIS server for specific hardware, Click on the server. Then on the right side pane, double click on ASP like this. The ASP Threads Per Processor Limit property specifies the maximum number of worker threads per processor that IIS creates.


2 Answers

You can accomplish what you want, but it is typically a bad idea. Several ASP.NET blog and CMS engines take this approach, because they want to be installable on a shared hosting system and not take a dependency on a windows service that needs to be installed. Typically they kick off a long running thread in Global.asax when the app starts, and have that thread process queued up tasks.

In addition to reducing resources available to IIS/ASP.NET to process requests, you also have issues with the thread being killed when the AppDomain is recycled, and then you have to deal with persistence of the task while it is in-flight, as well as starting the work back up when the AppDomain comes back up.

Keep in mind that in many cases the AppDomain is recycled automatically at a default interval, as well as if you update the web.config, etc.

If you can handle the persistence and transactional aspects of your thread being killed at any time, then you can get around the AppDomain recycling by having some external process that makes a request on your site at some interval - so that if the site is recycled you are guaranteed to have it start back up again automatically within X minutes.

Again, this is typically a bad idea.

EDIT: Here are some examples of this technique in action:

Community Server: Using Windows Services vs. Background Thread to Run Code at Scheduled Intervals Creating a Background Thread When Website First Starts

EDIT (from the far distant future) - These days I would use Hangfire.

like image 191
Bryan Batchelder Avatar answered Oct 06 '22 01:10

Bryan Batchelder


I disagree with the accepted answer.

Using a background thread (or a task, started with Task.Factory.StartNew) is fine in ASP.NET. As with all hosting environments, you may want to understand and cooperate with the facilities governing shutdown.

In ASP.NET, you can register work needing to stop gracefully on shutdown using the HostingEnvironment.RegisterObject method. See this article and the comments for a discussion.

(As Gerard points out in his comment, there's now also HostingEnvironment.QueueBackgroundWorkItem that calls down to RegisterObject to register a scheduler for the background item to work on. Overall the new method is nicer since it's task-based.)

As for the general theme that you often hear of it being a bad idea, consider the alternative of deploying a windows service (or another kind of extra-process application):

  • No more trivial deployment with web deploy
  • Not deployable purely on Azure Websites
  • Depending on the nature of the background task, the processes will likely have to communicate. That means either some form of IPC or the service will have to access a common database.

Note also that some advanced scenarios might even need the background thread to be running in the same address space as the requests. I see the fact that ASP.NET can do this as a great advantage that has become possible through .NET.

like image 38
John Avatar answered Oct 06 '22 00:10

John