在ExitWriterlock之后处置ReaderWriterlockslim
我有一个可以清理某些对象以及ReaderWriterlockslim的功能。但是我需要ReaderWriterlockslim作为作者锁定,以防止在我进行清理时读取数据。
ConcurrentDictionary<string, ReaderWriterLockSlim> RwLocks = new ConcurrentDictionary<string, ReaderWriterLockSlim>();
private ReaderWriterLockSlim GetRwLock(string key)
{
return RwLocks.GetOrAdd(key, _ => new ReaderWriterLockSlim());
}
public void CleanUp(string key)
{
ReaderWriterLockSlim rwLock = this.GetRwLock(key);
try
{
rwLock.EnterWriterLock();
// do some other clean up
this.RwLocks.TryRemove(key, out _);
}
finally
{
rwLock.ExitWriterLock();
// It is safe to do dispose here?
// could other thread enter the read lock or writer lock here?
// and the dispose will throw exceptions?
// What is the best practice to do the dispose?
rwLock.Dispose();
}
}
我有一个想法包装ReaderWriterlockslim
。您认为它可以解决问题或有任何潜在风险
public class ReaderWriterLockSlimWrapper
{
private ReaderWriterLockSlim rwLock;
private volatile bool disposed;
public ReaderWriterLockSlimWrapper()
{
rwLock = new ReaderWriterLockSlim();
disposed = false;
}
private void DisposeInternal()
{
if (!rwLock.IsReadLockHeld && !rwLock.IsUpgradeableReadLockHeld && !rwLock.IsWriteLockHeld)
{
rwLock.Dispose();
}
}
public void Dispose()
{
disposed = true;
DisposeInternal();
}
public void EnterReadLock()
{
rwLock.EnterReadLock();
}
public void ExitReadLock()
{
rwLock.ExitReadLock();
if (disposed)
{
DisposeInternal();
}
}
public void EnterWriteLock()
{
rwLock.EnterWriteLock();
}
public void ExitWriteLock()
{
rwLock.ExitWriteLock();
if (disposed)
{
DisposeInternal();
}
}
}
I have a function to clean up some objects as well as the ReaderWriterLockSlim. But I need the ReaderWriterLockSlim to lock as writer lock to prevent the other thread read the data while I am doing the clean up.
ConcurrentDictionary<string, ReaderWriterLockSlim> RwLocks = new ConcurrentDictionary<string, ReaderWriterLockSlim>();
private ReaderWriterLockSlim GetRwLock(string key)
{
return RwLocks.GetOrAdd(key, _ => new ReaderWriterLockSlim());
}
public void CleanUp(string key)
{
ReaderWriterLockSlim rwLock = this.GetRwLock(key);
try
{
rwLock.EnterWriterLock();
// do some other clean up
this.RwLocks.TryRemove(key, out _);
}
finally
{
rwLock.ExitWriterLock();
// It is safe to do dispose here?
// could other thread enter the read lock or writer lock here?
// and the dispose will throw exceptions?
// What is the best practice to do the dispose?
rwLock.Dispose();
}
}
I have an idea to wrap the ReaderWriterLockSlim
. Do you think it could solve the problem or have any potential risk
public class ReaderWriterLockSlimWrapper
{
private ReaderWriterLockSlim rwLock;
private volatile bool disposed;
public ReaderWriterLockSlimWrapper()
{
rwLock = new ReaderWriterLockSlim();
disposed = false;
}
private void DisposeInternal()
{
if (!rwLock.IsReadLockHeld && !rwLock.IsUpgradeableReadLockHeld && !rwLock.IsWriteLockHeld)
{
rwLock.Dispose();
}
}
public void Dispose()
{
disposed = true;
DisposeInternal();
}
public void EnterReadLock()
{
rwLock.EnterReadLock();
}
public void ExitReadLock()
{
rwLock.ExitReadLock();
if (disposed)
{
DisposeInternal();
}
}
public void EnterWriteLock()
{
rwLock.EnterWriteLock();
}
public void ExitWriteLock()
{
rwLock.ExitWriteLock();
if (disposed)
{
DisposeInternal();
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您尚未描述您打算使用两种机制的特定方案,既不是使用
clearup
/getrwlock
方法的第一个机制,也不适用于第二种机制ReaderWriterlockslimwrapper
类。所以我想问题是:答案是否定的,您的两种机制都充满了种族条件,并且无法保证原子能。在多线程方案中使用它们将导致不确定的行为,包括但不限于:
解释为什么您的机制有缺陷。一个一般说明是,每当您使用模式
时,如果(x.BooleanProperty)X.Method();
在多线程环境中,尽管booleanProperty
和方法
可能是单独的线程安全,您允许第二个线程在两个调用之间抢占当前线程,并使第一次检查的结果无效。附带说明,请注意,
ReaderWriterlockslim
不是交叉过程同步原始化。因此,即使您修复了机制,然后尝试在Web应用程序中使用它们,也可能会违反策略,因为Web服务器可能会随机决定回收当前过程并启动新过程。在这种情况下,Web应用程序可能会通过在两个进程上同时运行,在一段时间内跨越几秒钟甚至几分钟。You haven't described the specific scenario where you intend to use your two mechanisms, neither for the first one with the
CleanUp
/GetRwLock
methods, nor for the second one with theReaderWriterLockSlimWrapper
class. So I guess the question is:The answer is no, both of your mechanisms are riddled with race conditions, and offer no guarantees about atomicity. Using them in a multithreaded scenario would result in undefined behavior, including but not limited to:
ReaderWriterLockSlim
is normally expected to enforce. In order words it is possible that two threads will acquire a writer lock for the same key concurrently to each other, or concurrently with others threads that have acquired a reader lock for the same key, or both.Explaining why your mechanisms are flawed is quite involved. A general explanation is that whenever you use the pattern
if (x.BooleanProperty) x.Method();
in a multithreaded environment, although theBooleanProperty
and theMethod
might be individually thread-safe, you are allowing a second thread to preempt the current thread between the two invocations, and invalidate the result of the first check.As a side note, be aware that the
ReaderWriterLockSlim
is not a cross-process synchronization primitive. So even if you fix your mechanisms and then attempt to use them in a web application, the policies might still be violated because the web server might decide at random moments to recycle the current process and start a new one. In that case the web application might by running concurrently on two processes, for a period of time that spans a few seconds or even minutes.