开发者

ASP.NET multithreading & "thread has already entered the lock"

In an ASP.NET application, I have a resource that is protected by a ReaderWriterLockSlim.

Normal requests call EnterReadLock, access the resource, call ExitReadLock and return.

At one moment, I accidently forgot to put a call to ExitReadLock somewhere in my code. On the next request, I got an exception stating that the thread had already entered the lock.

Fair enough: if at the end of request A the thread does not exit the lock, and that same thread is used to process request B, and tries to enter the lock, it will throw.

Now, my question: is the following scenario possible? reasons?

  • thread begins to process request A
  • thread enters lock
  • thread does, say, sleep, or do some IO, and so becomes available
  • same thread begins to process request B, while request A is "on hold"
  • thread enters lock !! throws !!

If yes, what other solution do I have to protect said resource? Bearing in mind I want to use a ReaderWriterLockSlim because I also have other thread that may write to the resource?

edit: add some details:

1) This happens in the ProcessRequest method of an HttpHandler which generates, caches and serves images. These images are expensive to generate. So, the first request will generate and cache the image, and we want to put the other requests on hold while generating.

2) We have not tried to "reproduce" -- at the moment we're trying to know if it is possible or not that the same thread begins process开发者_如何学Going a request while already waiting for the image to become ready.

3) I am aware of the LockPolicyRecursion but I am not sure I fully understand its purpose, and whether it would be OK to set it to SupportsRecursion in our case.

edit: going further...

According to the document pointed to by Ryan below, a thread will block and not return to the pool as long as we don't engage into async operations. So once we've locked the thread waiting for EnterReadLock to complete, it won't return to the pool nor process any other request.

So 1) we should be safe but 2) we might starve the thread pool. Assuming we don't want to immediately return a dummy "please wait" image, what solutions do we have?


Yes, that is possible in ASP.NET. There are some places (async etc) where ASP.NET does thread-switching and uses different threads for a single request (at different points), which means that it is entirely possible that half way through a request that thread goes on to process another request.

At what points in the pipeline do you take/release the lock? Can you reduce this? Personally I would limit the thread duration to some synchronous method that is separated from the UI/presentation code. It won't be changing threads in the middle of a synchronous method.


A read-locked thread that's reused by the pool could definitely reenter the lock if it's requesting a read. Can a read-locked thread be reused by the pool? That I'm not sure of, but the read operation should be fast enough to avoid the race condition.

The thread pool should only reclaim a thread if it's idle (i.e., sleeping). So, you would expect that if your protected code doesn't cause the thread to go idle, then the thread shouldn't be reclaimed while it's in the lock - just make sure you exit the lock (always exit in a finally block)

If you want to ensure that you don't reenter the lock, then you'd need to block the thread with a Monitor (or a write lock); blocking threads are not released back to the pool.

EDIT: If you're generating the images, then you should be acquiring a write lock which will block all read locks. Neither the blocking, nor blocked, threads will be reused, so you shouldn't have an issue.

Source

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜