如何正确使用readerwriterlock

时间:2009-11-04 15:13:00

标签: c# .net multithreading readerwriterlock

您好我需要在我的方法中使用writerreaderlock。我想知道如何正确使用它。

我收到了ObjectA的词典

public class ObjectA
{
    public ReaderWriterLock RWL {get;set;}
    public ObjectB obj {get;set;}
    public ObjectA()
    {
        RWL = new ReaderWriterLock();
    }
}

public class ObjectB
{
    int TTL {get;set;}
    string Value {get;set;}
}

在我的方法中,我使用ObjectA的字典,键是Guid,所以假设当我调用dict [guid]时它总是返回我的ObjectA的一个实例(例如)

public foo()
{
    ObjecA objA = dict[guid];
    objA.RWL.AcquireReaderLock(500);
    if(objA.obj.TTL<=0)
    {
        objA.obj.RWL.AcquireWriterLock(1000);
        objA.obj.Value = DateTime.Now().ToString();
        objA.obj.RWL.ReleaseWriterLock();
    }else{
         int ttl = objA.obj.TTL;
         Interlocked.Decrement(ref ttl);
    }    
    objA.RWL.ReleaseReaderLock();
}

我真的不确定我在那边使用读者和作者,我是如何使用读写器锁来进行条件验证的呢?

1 个答案:

答案 0 :(得分:6)

此代码存在许多问题,包括:

  • 你实际上并没有在你的班级实例中减少TTL--正如尼古拉指出的那样,你正在递减一个局部变量! Interlocked.Decrement(ref objA.obj.TTL)是如何正确执行此操作的。
  • 你没有设置一个初始TTL值,所以它总是为零(除非其他一些代码正在设置它,这对于你通常想要所有线程安全相关代码的线程敏感类来说可能不明智在同一个班级,以避免忘记谁在做什么)。
  • 您应该使用ReaderWriterLockSlim,现在比较早的ReaderWriterLock类更受欢迎。请参阅后一个超链接了解原因。
  • 获取写锁定时,如果您已经有读锁定,则需要升级锁定 - 锁定类通常有一个单独的方法。类似地,在升级之后,释放锁需要一种方法来释放锁,而不是一个释放写锁而另一个释放先前的读锁。
  • 你需要处理你无法获得锁的失败案例。
  • 您希望将代码包装在usingtry/finally块中,以确保即使发生异常也可以释放资源。

也值得考虑你是否确实需要使用读/写锁,而不是使用像lock{} statement这样简单的东西。即使对于那些熟悉这些API和概念的开发人员来说,即使在那时他们通常只保留用于性能最关键的地方(1000秒+每秒),也很难获得正确的读取器/写入器锁定并避免死锁。换句话说,使用lock{}开始使用更简单的方法可能会更好,如果性能不可接受,则只能使用ReaderWriterLockSlim

作为一个起点,我建议您在问题中添加更多信息:

  • 首先,包括您正在尝试做的事情的高级描述,包括功能和性能的高级要求。这可以帮助我们推荐正确的解决方案,并了解读/写锁是否是正确的方法。
  • 尝试用伪代码或简单的英文写出你希望代码的行为,包括你想如何解决上面的逻辑问题(例如,当超时发生时该做什么,如何设置TTL等)
  • 修改您的代码示例以包含针对我上面提到的一些/所有问题的修复

我向您保证,如果您在问题中包含此附加信息,您将获得更好的答案,可以帮助您解决任何剩余的代码问题。 : - )

相关问题