首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReaderWriterLockSlim出错

ReaderWriterLockSlim出错
EN

Stack Overflow用户
提问于 2012-04-25 01:45:18
回答 2查看 2K关注 0票数 8

我得到了一个例外

代码语言:javascript
复制
  The read lock is being released without being held.
代码语言:javascript
复制
      at System.Threading.ReaderWriterLockSlim.ExitReadLock()          at .. GetBreed(String)

下面是代码中访问锁的唯一位置。如您所见,没有递归。我很难理解这个异常是如何发生的。

代码语言:javascript
复制
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();
        }
}  
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-25 02:00:44

我猜你有一些可重入的东西,它在获取锁时抛出了一个异常。无论你是“使用锁”,“尝试”还是“尝试”,还是“使用锁”,这都是一个两难的问题,但是“使用锁”,“尝试”的失败案例更少(“在获取和尝试之间中止”的可能性很小,你不需要强调)。

将"take the lock“移到"try”之外,看看实际的异常是什么。

问题很可能是你没有获得锁(可能是可重入性),然后试图解锁你没有获得的东西。这可能意味着在获取锁的原始代码中出现异常,这是由于尝试释放两次而只获取一次。

注意: Monitor有新的重载和"ref bool“参数来帮助这个场景-但没有其他锁类型。

票数 3
EN

Stack Overflow用户

发布于 2012-04-25 02:48:36

实例化RWLS时使用LockRecursionPolicy.SupportsRecursion。如果错误消失了,那么实际上你确实涉及到了某种类型的递归。也许是在你没有发布的代码中?

如果您真的很关心如何从中获得最大的并发性(因为我怀疑您正在使用RWLS),那么您可以使用双重检查锁定模式。注意到你的原始代码已经有这种感觉了吗?那么,为什么要绕着布什转呢?就这么做。

在下面的代码中,请注意我是如何始终将Breeds引用视为不可变的,然后在lock中重新检查、复制、更改和交换引用。

代码语言:javascript
复制
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;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10303191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档