我的部分代码隐藏:
object _sync = new object();
private async void OnKeyDown(object sender, KeyEventArgs e) {
if (!Monitor.TryEnter(_sync)) return;
Trace.Write("taken...");
await Task.Delay(TimeSpan.FromSeconds(5));
Trace.WriteLine(" done");
Monitor.Exit(_sync);
}
输出(在不到 5 秒内按几次):
taken...taken...taken... done
done
done
怎么会?? _sync
锁从未被占用,为什么?
最佳答案
混合使用 Monitor
和 await
是……有点冒险。看起来您正在尝试做的是确保它一次只运行一次。我怀疑 Interlocked
可能更简单:
object _sync = new object();
int running = 0;
private async void OnKeyDown(object sender, KeyEventArgs e) {
if(Interlocked.CompareExchange(ref running, 1, 0) != 0) return;
Trace.Write("taken...");
await Task.Delay(TimeSpan.FromSeconds(5));
Trace.WriteLine(" done");
Interlocked.Exchange(ref running, 0);
}
请注意,您可能还想考虑如果发生错误等会发生什么;值如何重置?您可能可以使用 try
/finally
:
if(Interlocked.CompareExchange(ref running, 1, 0) != 0) return;
try {
Trace.Write("taken...");
await Task.Delay(TimeSpan.FromSeconds(5));
Trace.WriteLine(" done");
} finally {
Interlocked.Exchange(ref running, 0);
}
关于c# - Monitor.TryEnter 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21410320/