C# NET多线程&&引用;线程已进入锁“中”;
在ASP.NET应用程序中,我有一个受ReaderWriterLockSlim保护的资源 普通请求调用EnterReadLock、访问资源、调用ExitReadLock并返回 有一刻,我不小心忘记在代码中的某个地方调用ExitReadLock。在下一个请求中,我得到一个异常,声明线程已经进入锁 足够公平:如果在请求A结束时线程没有退出锁,并且该线程用于处理请求B,并尝试进入锁,它将抛出 现在,我的问题是:以下情况可能吗?原因是什么C# NET多线程&&引用;线程已进入锁“中”;,c#,asp.net,multithreading,C#,Asp.net,Multithreading,在ASP.NET应用程序中,我有一个受ReaderWriterLockSlim保护的资源 普通请求调用EnterReadLock、访问资源、调用ExitReadLock并返回 有一刻,我不小心忘记在代码中的某个地方调用ExitReadLock。在下一个请求中,我得到一个异常,声明线程已经进入锁 足够公平:如果在请求A结束时线程没有退出锁,并且该线程用于处理请求B,并尝试进入锁,它将抛出 现在,我的问题是:以下情况可能吗?原因是什么 线程开始处理请求 线程进入锁 线程执行,比如说,睡眠,或者执行
- 线程开始处理请求
- 线程进入锁
- 线程执行,比如说,睡眠,或者执行一些IO,因此变得可用
- 同一线程开始处理请求B,而请求A处于“保留”状态
- 线程进入锁!!扔强>
因此1)我们应该是安全的,但2)我们可能会耗尽线程池。假设我们不想立即返回虚拟的“请稍候”图像,我们有什么解决方案?是的,在ASP.NET中这是可能的。在某些地方(异步等),ASP.NET会进行线程切换,并对单个请求使用不同的线程(在不同的点),这意味着在请求中途,线程完全可能继续处理另一个请求
在管道中的什么位置取/释放锁?你能减少这个吗?就我个人而言,我会将线程持续时间限制为与UI/表示代码分离的某个同步方法。它不会在同步方法中间改变线程。< P>由池重用的读锁定线程如果请求读,肯定可以重新进入锁。池是否可以重用读锁定线程?我不确定,但读取操作应该足够快,以避免竞争条件 线程池只应在线程空闲(即休眠)时回收线程。因此,如果受保护的代码没有导致线程空闲,那么线程在锁中时就不应该被回收——只要确保退出锁(始终在
finally
块中退出)
如果要确保不重新输入锁,则需要使用监视器(或写锁)阻止线程;阻塞线程不会释放回池
编辑:如果生成图像,则应获取一个写锁,该锁将阻止所有读锁。阻塞线程和阻塞线程都不会被重用,因此您不应该有问题
@Mauricio-虽然链接是有效的,但我认为这会隐藏真正的问题;这段代码并不是故意使用递归锁。@Mauricio:我不确定我是否完全理解LockRecursionPolicy的确切目的,也不确定它是否被用于这种情况@马克:没错。但是我想不出其他方法来做这件事?对不起,误解了这个问题。请参阅我的编辑:获取并释放HttpHandler的ProcessRequest中的锁。一个线程可能会持有锁(在写模式下)一段时间,并在持有锁的同时对某些IO执行。@Ryan:“阻塞线程不会释放回池”你能给我指一些记录这一点的页面吗?我自己找不到。@Ryan:Oops,我错过了你的“源”链接。目前正在阅读。