Ada*_*ger 15 c# thread-safety readerwriterlockslim
我有一个使用ReaderWriterLockSlim的类,它有一个read方法和一个write方法,它使用read方法来检索要修改的元素.一个简单的例子是:
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.
}
Run Code Online (Sandbox Code Playgroud)
如上所述,此代码LockRecursionException在调用时抛出,ChangeFoo()因为在GetFoo()尝试输入读锁定时已经保持写锁定.
我已经检查了文档ReaderWriterLockSlim,我可以LockRecursionPolicy.SupportsRecursion用来允许上面的工作.但是,文档还建议不应将此用于任何新开发,并且只应在升级现有代码时使用.
鉴于此,在write方法可以使用只读方法检索需要修改的事物的情况下,实现相同结果的最佳实践是什么?
Pol*_*ity 27
您可以将您的班级划分为暴露的方法和私有的内部方法.内部方法执行像抓取一样的逻辑,公共方法执行锁定.例:
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];
}
}
Run Code Online (Sandbox Code Playgroud)