非阻塞锁定

Der*_*ike 9 .net c# multithreading

我想为一个重复操作开始一些新的线程.但是当这样的操作已经在进行中时,我想放弃当前的任务.在我的场景中,我只需要非常新的数据 - 丢弃的数据不是问题.

在MSDN中我找到了这个Mutex类,但据我所知,它等待轮到它,阻塞当前线程.另外我想问你:.NET框架中是否存在某些内容,它执行以下操作:

  1. 某些方法M是否已被执行?
  2. 如果是这样,return(并且让我增加一些统计计数器)
  3. 如果没有,请在新线程中启动方法M.

Rob*_*ine 24

lock(someObject)你可能遇到过的陈述是围绕Monitor.Enter和的语法糖Monitor.Exit.

但是,如果您以这种更详细的方式使用显示器,您还可以使用Monitor.TryEnter它来检查您是否能够获得锁定 - 因此检查是否有其他人已经拥有它并正在执行代码.

所以不是这样的:

var lockObject = new object(); 

lock(lockObject)
{
    // do some stuff
}
Run Code Online (Sandbox Code Playgroud)

试试这个(选项1):

int _alreadyBeingExecutedCounter;
var lockObject = new object();

if (Monitor.TryEnter(lockObject))
{
   // you'll only end up here if you got the lock when you tried to get it - otherwise you'll never execute this code.

    // do some stuff

    //call exit to release the lock
    Monitor.Exit(lockObject);
}
else
{
    // didn't get the lock - someone else was executing the code above - so I don't need to do any work!
   Interlocked.Increment(ref _alreadyBeingExecutedCounter);
}
Run Code Online (Sandbox Code Playgroud)

(你可能想尝试一下..确保锁定被释放)

或者完全放弃显式锁定并执行此操作

(选项2)

private int _inUseCount;

public void MyMethod()
{
    if (Interlocked.Increment(ref _inUseCount) == 1)
    {
        // do dome stuff    
    }
    Interlocked.Decrement(ref _inUseCount);
}
Run Code Online (Sandbox Code Playgroud)

[编辑:回答您的问题this]

否-不使用thislock的.创建一个私有范围的对象作为您的锁.

否则你有这个潜在的问题:

public class MyClassWithLockInside
{
    public void MethodThatTakesLock()
    {
        lock(this)
        {
            // do some work
        }
    }
 }

public class Consumer
{
    private static MyClassWithLockInside _instance = new MyClassWithLockInside();

    public void ThreadACallsThis()
    {
          lock(_instance)
          {
              // Having taken a lock on our instance of MyClassWithLockInside,
              // do something long running
              Thread.Sleep(6000);
           }
    }

    public void ThreadBCallsThis()
    {
         // If thread B calls this while thread A is still inside the lock above,
         // this method will block as it tries to get a lock on the same object
         // ["this" inside the class = _instance outside]
         _instance.MethodThatTakesLock();
    }  
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,一些外部代码设法通过锁定外部可访问的东西来破坏我们类的内部锁定.

创建一个你控制的私有对象,以及你班级以外没有人可以访问的私有对象,以避免出现这些问题要好得多; 这包括不使用this或类型本身typeof(MyClassWithLockInside)锁定.