c# - Monitor.TryEnter 不起作用

标签 c# wpf multithreading

我的部分代码隐藏:

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 锁从未被占用,为什么?

最佳答案

混合使用 Monitorawait 是……有点冒险。看起来您正在尝试做的是确保它一次只运行一次。我怀疑 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/

相关文章:

c# - 动态数据输入表单

c# - Prism RequestNavigate 在启动时立即从 PrismApplication 导航

c# - BCrypt 是一种在 C# 中使用的好哈希算法吗?我在哪里可以找到它?

c# - 方法调用和方法入口 (C#) 之间发生了什么?

multithreading - 在 servlet 容器中启动线程池

c# - 线程中的 TopMost 表单?

java - java中无法同步方法

c# - 具有辅助角色的 Azure 服务总线主题和订阅

wpf - 如何让 XBAP 在浏览器中运行而不是在 Windows 7 上下载?

c# - 来自代码的 Wpf 动画