如果另一个线程正在执行它,则退出方法

时间:2012-09-13 18:05:32

标签: c# thread-safety

我在多线程应用程序中有一个方法,并且在调用此方法时我想要以下行为:

  1. 如果当前没有其他线程正在执行该方法,请执行它。
  2. 如果另一个线程当前正在执行该方法,则退出该方法而不执行它。
  3. C#中的lock语句对于等待线程完成执行非常有用,但我不希望序列化对此方法的访问,而是在另一个线程执行时绕过执行所述方法。

4 个答案:

答案 0 :(得分:13)

您可以使用Monitor.TryEnter执行此操作,但可能更简单:Interlocked:

int executing; // make this static if you want this one-caller-only to
               // all objects instead of a single object
void Foo() {
    bool won = false;
    try {
        won = Interlocked.CompareExchange(ref executing, 1, 0) == 0;
        if(won) {
           // your code here
        }
    } finally {
        if(won) Interlocked.Exchange(ref executing, 0);
    }

}

答案 1 :(得分:9)

我想我不明白......如果它一次只能由一个线程调用,为什么多个线程都会调用它开始?

无论如何,您可以使用Monitor.TryEnter()。如果它无法获得锁定,它不会阻止并返回false。在这种情况下,您可以从函数返回。

答案 2 :(得分:0)

这是一个用于此目的的辅助方法:

static class Throttle
{
    public static void RunExclusive(ref int isRunning, Action action)
    {
        if (isRunning > 0) return;

        bool locked = false;
        try
        {
            try { }
            finally
            {
                locked = Interlocked.CompareExchange(ref isRunning, 1, 0) == 0;
            }

            if (locked) action();
        }
        finally 
        { 
            if (locked) 
                Interlocked.Exchange(ref isRunning, 0); 
        }
    }
}

并使用它:

private int _isTuning = 0;
private void Tune() { ... }

...

Throttle.RunExclusive(ref _isTuning, Tune);

答案 3 :(得分:-1)

在其他地方创建bool变量,在start方法时设置为true,在退出方法时设置为false,在运行方法之前检查变量是否为false然后运行else从方法退出