不要使用 Dispatcher.Invoke,因为它可能在你的延迟初始化 Lazy 中导致死锁


WPF 中为了 UI 的跨线程访问,提供了 Dispatcher 线程模型。其 Invoke 方法,无论在哪个线程调用,都可以让传入的方法回到 UI 线程。

然而,如果你在 Lazy 上下文中使用了 Invoke,那么当这个 Lazy 跨线程并发时,极有可能导致死锁。本文将具体说说这个例子。


本文内容

      • 一段死锁的代码
      • 此死锁的触发条件
      • 此死锁的原因
      • 此死锁的解决方法
      • 更多死锁问题

使用 Task.Wait()?立刻死锁(deadlock) - walterlv
  • 不要使用 Dispatcher.Invoke,因为它可能在你的延迟初始化 Lazy 中导致死锁 - walterlv
  • 在有 UI 线程参与的同步锁(如 AutoResetEvent)内部使用 await 可能导致死锁
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况 - walterlv
  • 解决方法:

    • 在编写异步方法时,使用 ConfigureAwait(false) 避免使用者死锁 - walterlv
    • 将 async/await 异步代码转换为安全的不会死锁的同步代码(使用 PushFrame) - walterlv