我在多线程应用程序中有一个方法,并且在调用此方法时我想要以下行为:
C#中的lock
语句对于等待线程完成执行非常有用,但我不希望序列化对此方法的访问,而是在另一个线程执行时绕过执行所述方法。
答案 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从方法退出