tags:

views:

306

answers:

7

Recently, the book on threading for Winforms application (Concurrent programming on Windows by Joe Duffy) was released. This book, focused on winforms, is 1000 pages.

What gotchas are there in ASP.NET threading? I'm sure there are plenty of gotchas to be aware of when implementing threading in ASP.NET. What should I be aware of?

Thanks

+3  A: 

Jeff Richter over at Wintellect has a library called PowerThreading. It is very useful if you are developing applications on .NET. => Power Threading Library

Check for his presentations online at various events.

CodeToGlory
I second this recommendation. And be sure to get on the Yahoo group while you're there.
Boydski
This does absolutely nothing to answer the question. Down voted.
Chris
+1  A: 

The immediate thing that comes to mind is, why would you "implement threading" in ASP.NET.

You do need to be conscious all the time that ASP.NET is multi-threaded since many requests can be processed simulatenously each in its own thread. So for example use of static fields needs to take threading into account.

However its rare that you would want to spin up a new thread in code yourself.

As far as the usual winforms issues with threading in the UI is concerned these issues are not present in ASP.NET. There is no window based message pump to worry about.

AnthonyWJones
Is it safe to put instance variables in codebehind files?
Adam Asham
Instance variables in codebehind will be separate for each instance of the page. Each request to the same page will get a new instance, so, in that sense, it's safe. Multiple threads spawned == "not so safe"
John Saunders
@Adam: As John says an instance is generally created per request and used by only one thread. If you write a raw handler (.ashx) it is possible to indicate that an instance can be re-used by subsequent requests but it is still thread-safe.
AnthonyWJones
+4  A: 

Since each http request received by IIS is processed separately, on it's own thread anyway, the only issues you should have is if you kick off some long running process from within the scope of a single http request. In that case, I would put such code into a separate referenced dependant assembly, coded like a middle-tier component, with no dependance or coupling to the ASP.Net model at all, and handle whatever concurrency issues arose within that assembly separately, without worrying about the ASP.Net model at all...

Charles Bretana
A: 

It is possible to create asynchronous pages in ASP.NET. These will perform all steps up to a certain point. These steps will include asynchronously fetching data, for instance. When all the asynchronous tasks have completed, the remainder of the page lifecycle will execute. In the meantime, a worker thread was not tied up waiting for database I/O to complete.

In this model, all extra threads are executing while the request, and the page instance, and all the controls, still exist. You have to be careful when starting your own threads, that, by the time the thread executes, it's possible that the request, page instance, and controls will have been Disposed.

Also, as usual, be certain that multiple threads will actually improve performance. Often, additional threads will make things worse.

John Saunders
A: 

First, are you talking about asynchronous ASP.NET? Or using the ThreadPool/spinning up your own threads?

If you aren't talking about asynchronous ASP.NET, the main question to answer is: what work would you be doing in the other threads and would the work be specific to a request/response cycle, or is it more about processing global tasks in the background?

EDIT

If you need to handle concurrent operations (a better term than multi-threaded IMO) for a given request/response cycle, then use the asynchronous features of ASP.NET. These provide an abstraction over IIS's support for concurrency, allowing the server to process other requests while the current request is waiting for work to complete.

For background processing of global tasks, I would not use ASP.NET at all. You should assume that IIS will recycle your AppPool at a random point in time. You also should not assume that IIS will run your AppPool on any sort of schedule. Any important background processing should be done outside of IIS, either as a scheduled task or a Windows Service. The approach I usually take is to have a Windows Service and a shared work-queue where the web-site can post work items. The queue can be a database table, a reliable message-based queue (MSMQ, etc), files on the file system, etc.

Brannon
I'm actually talking about both. The work would be specific to a request/response. It will also be about processing global, frequent tasks in the background. No actual case here, but this thread is for future knowledge.
dotnetdev
+1  A: 

The gotchas are pretty much the same as in any multithreaded application.

The classes involved in processing a request (Page, Controls, HttpContext.Current, ...) are specific to that request so don't need any special handling.

Similarly for any classes you instantiate as local variables or fields within these classes, and for access to Session.

But, as usual, you need to synchronize access to shared resources such as:

  • Static (C#) / Shared(VB.NET) references.
  • Singletons
  • External resources such as the file system ... etc...

I've seen threading bugs too often in ASP.NET apps, e.g. a singleton being used by multiple concurrent requests without synchronization, resulting in user A seeing user B's data.

Joe
+2  A: 

Usually you are encouraged to use the thread pool in .Net because it of the many benefits of having things managed on your behalf.....but NOT in ASP.net.

Since ASP.net is already multi-threaded, it uses the thread pool to serve requests that are mapped to the ASP.net ISAPI filter, and since the thread pool is fixed in size, by using it you are basically taking threads away that are set aside to do the job of handling request.

In small, low-traffic websites, this is not an issue, but in larger, high-traffic websites you end up competing for and consuming threads that the ASP.net process relies on.

If you want to use threading, it is fine to do something like....

   Thread thread = new Thread(threadStarter);
   thread.IsBackground = true;
   thread.Start();

but with a warning: be sure that the IsBackground is set to true because if it isn't the thread exists in the foreground and will likely prevent the IIS worker process from recycling or restarting.

Ray Womack