我得到了一个例外
The read lock is being released without being held. at System.Threading.ReaderWriterLockSlim.ExitReadLock() at .. GetBreed(String)下面是代码中访问锁的唯一位置。如您所见,没有递归。我很难理解这个异常是如何发生的。
static readonly Dictionary<string, BreedOfDog> Breeds
= new Dictionary<string,BreedOfDog>();
static BreedOfDog GetBreed(string name)
{
try
{
rwLock.EnterReadLock();
BreedOfDog bd;
if (Breeds.TryGetValue(name, out bd))
{
return bd;
}
}
finally
{
rwLock.ExitReadLock();
}
try
{
rwLock.EnterWriteLock();
BreedOfDog bd;
//make sure it hasn't been added in the interim
if (Breeds.TryGetValue(t, out bd)
{
return bd;
}
bd = new BreedOfDog(name); //expensive to fetch all the data needed to run the constructor, hence the caching
Breeds[name] = bd;
return bd;
}
finally
{
rwLock.ExitWriteLock();
}
} 发布于 2012-04-25 02:00:44
我猜你有一些可重入的东西,它在获取锁时抛出了一个异常。无论你是“使用锁”,“尝试”还是“尝试”,还是“使用锁”,这都是一个两难的问题,但是“使用锁”,“尝试”的失败案例更少(“在获取和尝试之间中止”的可能性很小,你不需要强调)。
将"take the lock“移到"try”之外,看看实际的异常是什么。
问题很可能是你没有获得锁(可能是可重入性),然后试图解锁你没有获得的东西。这可能意味着在获取锁的原始代码中出现异常,这是由于尝试释放两次而只获取一次。
注意: Monitor有新的重载和"ref bool“参数来帮助这个场景-但没有其他锁类型。
发布于 2012-04-25 02:48:36
实例化RWLS时使用LockRecursionPolicy.SupportsRecursion。如果错误消失了,那么实际上你确实涉及到了某种类型的递归。也许是在你没有发布的代码中?
如果您真的很关心如何从中获得最大的并发性(因为我怀疑您正在使用RWLS),那么您可以使用双重检查锁定模式。注意到你的原始代码已经有这种感觉了吗?那么,为什么要绕着布什转呢?就这么做。
在下面的代码中,请注意我是如何始终将Breeds引用视为不可变的,然后在lock中重新检查、复制、更改和交换引用。
static volatile Dictionary<string, BreedOfDog> Breeds = new Dictionary<string,BreedOfDog>();
static readonly object LockObject = new object();
static BreedOfDog GetBreed(string name)
{
BreedOfDog bd;
if (!Breeds.TryGetValue(name, out bd))
{
lock (LockObject)
{
if (!Breeds.TryGetValue(name, out bd))
{
bd = new BreedOfDog(name);
var copy = new Dictionary<string, BreedOfDog>(Breeds);
copy[name] = bd;
Breeds = copy;
}
}
}
return bd;
}https://stackoverflow.com/questions/10303191
复制相似问题