我有一个使用带有读取方法的ReaderWriterLockSlim的类和一个使用read方法来检索要修改的元素的write方法。一个简单的例子是:
class FooLocker
{
ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
List<Foo> fooList = new List<Foo>();
public void ChangeFoo(int index, string bar)
{
locker.EnterWriteLock();
try
{
Foo foo = GetFoo(index);
foo.Bar = bar;
}
finally
{
locker.ExitWriteLock();
}
}
public Foo GetFoo(int index)
{
locker.EnterReadLock(); //throws System.Threading.LockRecursionException
try
{
return fooList[index];
}
finally
{
locker.ExitReadLock();
}
}
//snipped code for adding instances etc.
}
如上所述,此代码在调用LockRecursionException
时抛出ChangeFoo()
,因为当GetFoo()
尝试输入读锁定时,已经保持写锁定。
我查看了ReaderWriterLockSlim
的文档,我可以使用LockRecursionPolicy.SupportsRecursion
来完成上述工作。但是,文档还建议不要将其用于任何新开发,只应在升级现有代码时使用。
鉴于此,如果write方法可以使用只读方法来检索需要修改的内容,那么实现相同结果的最佳实践是什么?
答案 0 :(得分:24)
您可以将您的课程分为暴露方法和私人内部方法。内部方法执行像抓取一样的逻辑,公共方法执行锁定。例如:
class FooLocker
{
ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
List<Foo> fooList = new List<Foo>();
public void ChangeFoo(int index, string bar)
{
locker.EnterWriteLock();
try
{
Foo foo = UnsafeGetFoo(index);
foo.Bar = bar;
}
finally
{
locker.ExitWriteLock();
}
}
public Foo GetFoo(int index)
{
locker.EnterReadLock();
try
{
return UnsafeGetFoo(index);
}
finally
{
locker.ExitReadLock();
}
}
private Foo UnsafeGetFoo(int index)
{
return fooList[index];
}
}