C# NET多线程&&引用;线程已进入锁“中”;

C# NET多线程&&引用;线程已进入锁“中”;,c#,asp.net,multithreading,C#,Asp.net,Multithreading,在ASP.NET应用程序中,我有一个受ReaderWriterLockSlim保护的资源 普通请求调用EnterReadLock、访问资源、调用ExitReadLock并返回 有一刻,我不小心忘记在代码中的某个地方调用ExitReadLock。在下一个请求中,我得到一个异常,声明线程已经进入锁 足够公平:如果在请求A结束时线程没有退出锁,并且该线程用于处理请求B,并尝试进入锁,它将抛出 现在,我的问题是:以下情况可能吗?原因是什么 线程开始处理请求 线程进入锁 线程执行,比如说,睡眠,或者执行

在ASP.NET应用程序中,我有一个受ReaderWriterLockSlim保护的资源

普通请求调用EnterReadLock、访问资源、调用ExitReadLock并返回

有一刻,我不小心忘记在代码中的某个地方调用ExitReadLock。在下一个请求中,我得到一个异常,声明线程已经进入锁

足够公平:如果在请求A结束时线程没有退出锁,并且该线程用于处理请求B,并尝试进入锁,它将抛出

现在,我的问题是:以下情况可能吗?原因是什么

  • 线程开始处理请求
  • 线程进入锁
  • 线程执行,比如说,睡眠,或者执行一些IO,因此变得可用
  • 同一线程开始处理请求B,而请求A处于“保留”状态
  • 线程进入锁!!扔
如果是,我还需要什么解决方案来保护上述资源?请记住,我想使用ReaderWriterLockSlim,因为我还有其他可能写入资源的线程

编辑:添加一些详细信息:

1) 这发生在HttpHandler的ProcessRequest方法中,HttpHandler生成、缓存和服务图像。生成这些图像的成本很高。因此,第一个请求将生成并缓存图像,我们希望在生成图像时将其他请求搁置

2) 我们还没有尝试“复制”——目前我们正在尝试知道是否可能,同一线程在等待映像准备就绪时开始处理请求

3) 我知道LockPolicyRecursion,但我不确定我是否完全理解它的用途,以及在我们的情况下是否可以将其设置为SupportsRecursion

编辑:继续

根据Ryan在下面提到的文档,只要我们不参与异步操作,线程就会阻塞并且不会返回池。因此,一旦我们锁定了等待EnterReadLock完成的线程,它将不会返回池,也不会处理任何其他请求


因此1)我们应该是安全的,但2)我们可能会耗尽线程池。假设我们不想立即返回虚拟的“请稍候”图像,我们有什么解决方案?

是的,在ASP.NET中这是可能的。在某些地方(异步等),ASP.NET会进行线程切换,并对单个请求使用不同的线程(在不同的点),这意味着在请求中途,线程完全可能继续处理另一个请求


在管道中的什么位置取/释放锁?你能减少这个吗?就我个人而言,我会将线程持续时间限制为与UI/表示代码分离的某个同步方法。它不会在同步方法中间改变线程。

< P>由池重用的读锁定线程如果请求读,肯定可以重新进入锁。池是否可以重用读锁定线程?我不确定,但读取操作应该足够快,以避免竞争条件

线程池只应在线程空闲(即休眠)时回收线程。因此,如果受保护的代码没有导致线程空闲,那么线程在锁中时就不应该被回收——只要确保退出锁(始终在
finally
块中退出)

如果要确保不重新输入锁,则需要使用监视器(或写锁)阻止线程;阻塞线程不会释放回池

编辑:如果生成图像,则应获取一个写锁,该锁将阻止所有读锁。阻塞线程和阻塞线程都不会被重用,因此您不应该有问题


@Mauricio-虽然链接是有效的,但我认为这会隐藏真正的问题;这段代码并不是故意使用递归锁。@Mauricio:我不确定我是否完全理解LockRecursionPolicy的确切目的,也不确定它是否被用于这种情况@马克:没错。但是我想不出其他方法来做这件事?对不起,误解了这个问题。请参阅我的编辑:获取并释放HttpHandler的ProcessRequest中的锁。一个线程可能会持有锁(在写模式下)一段时间,并在持有锁的同时对某些IO执行。@Ryan:“阻塞线程不会释放回池”你能给我指一些记录这一点的页面吗?我自己找不到。@Ryan:Oops,我错过了你的“源”链接。目前正在阅读。