如何锁定方法内容

use*_*787 5 c# multithreading locking

我有一个可以从许多线程调用的方法,但我只是希望第一个线程在方法内部做一些逻辑.所以,我打算使用一个布尔变量.进来的第一个线程将布尔变量设置为false(以防止进一步的线程进入),并执行方法逻辑.

来到此方法的后续线程将检查布尔变量.因为第1个线程将其设置为false,所以它们将跳过方法逻辑.

在代码中,这样的事情:

private void myMethod()
{
   if (firsTime)  //set to true in the constructor
   {
      firstTime = false; //To prevent other thread to come inside here.
      //method logic
   }
}
Run Code Online (Sandbox Code Playgroud)

我想使用锁来执行此操作,但不确定将其放在何处.

如果我锁定"if"以将firstTime更改为false,则可能的2个或更多线程已经进入if(不想要这个).

如果我在"if"之外锁定以将firstTime更改为false,那么第一个线程怎么能进入if执行方法逻辑,如果firstTime它已经设置为false?

我的问题是:如何锁定以获得所需的功能?(设置布尔和执行方法逻辑的第一个线程).

我无法锁定所有方法逻辑,因为这将是一个非常耗时的操作.

Ser*_*rvy 7

您可以Interlocked.Exchange用来解决这个问题.它将给定变量的值设置为指定值,并返回以前在变量中的值,并且它将以原子方式完成所有操作.这样做将确保只有一个线程将运行以下代码if:

private static int isFirst = 1;
public static void Foo()
{
    if (Interlocked.Exchange(ref isFirst, 0) == 1)
    {
        //DoStuff
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,Interlocked.Exchange没有带有a的重载bool,这就是为什么你被迫使用int(或其他类型),使用1for true和0false.

如果您想要使用的解决方案lock,而不是Interlocked,您可以通过使用其他本地bool值来实现:

private static bool isFirst = true;
private static object key = new object();
public static void Foo()
{
    bool amFirst;
    lock (key)
    {
        amFirst = isFirst;
        isFirst = false;
    }

    if (amFirst)
    {
        //DoStuff
    }
}
Run Code Online (Sandbox Code Playgroud)