如何在C#中编写条件锁?

seb*_*mez 7 .net c# multithreading locking

问题是我一直在使用lock语句来保护我的代码的关键部分,但是现在,我意识到我可以允许并发执行那些关键代码是满足某些条件的.
有没有办法调节锁?

Tom*_*lak 9

我认为那个问题叫"竞争条件!".如果在检查后不久条件从true变为false,但在线程进入代码的关键部分之前怎么办?或者一个线程正在执行它?

  • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论。- [来自评论](/review/low-quality-posts/11336708) (3认同)

小智 8

我不是线程专家,但听起来你可能正在寻找这样的东西(双重检查锁定).想法是在获得锁之前和之后检查条件.

private static object lockHolder = new object();

if (ActionIsValid()) {
  lock(lockHolder) {
    if (ActionIsValid()) {
       DoSomething();    
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


mar*_*jne 7

bool locked = false;
if (condition) {
    Monitor.Enter(lockObject);
    locked = true;
}
try {
    // possibly critical section
}
finally {
    if (locked) Monitor.Exit(lockObject);
}
Run Code Online (Sandbox Code Playgroud)

编辑:是的,有一个竞争条件,除非您可以确保在线程进入时条件是恒定的.


Amy*_*y B 6

Action doThatThing = someMethod;

if (condition)
{
  lock(thatThing)
  {
     doThatThing();
  }
}
else
{
  doThatThing();
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 5

实际上,为了避免出现竞争状况,我很想在ReaderWriterLockSlim这里使用-将并发访问视为读锁定,而将独占访问视为写锁定。这样,如果条件发生变化,您将不会最终在该区域盲目执行某些不适当的代码(错误地认为它是安全的);有点冗长,但是(格式化为空格):

        if (someCondition) {
            lockObj.EnterReadLock();
            try { Foo(); }
            finally { lockObj.ExitReadLock(); }
        } else {
            lockObj.EnterWriteLock();
            try { Foo(); }
            finally { lockObj.ExitWriteLock(); }
        }
Run Code Online (Sandbox Code Playgroud)