我在多线程应用程序中有一个方法,我希望在调用此方法时出现以下行为:
- 如果当前没有其他线程正在执行该方法,则执行它。
- 如果另一个线程当前正在执行该方法,则退出该方法而不执行它。
C# 中的lock
语句对于等待线程完成执行很有用,但我不想序列化对此方法的访问,而是在另一个线程执行时绕过执行所述方法。
我在多线程应用程序中有一个方法,我希望在调用此方法时出现以下行为:
C# 中的lock
语句对于等待线程完成执行很有用,但我不想序列化对此方法的访问,而是在另一个线程执行时绕过执行所述方法。
您可以使用 Monitor.TryEnter 执行此操作,但可能更简单:互锁:
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);
}
}
我想我不明白......如果一次只能由一个线程调用,为什么要多个线程调用它?
无论如何,您可以使用Monitor.TryEnter()。false
如果获取锁失败,它不会阻塞并返回。在这种情况下,您可以从函数中返回。
在其他地方创建布尔变量,在启动方法时设置为真,在方法退出时设置为假,在运行方法之前检查变量是否为假然后运行否则退出方法
这是一个用于此目的的辅助方法:
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);