【问题标题】:Thread.Join() causes processing of window messages in WPF applicationThread.Join() 导致在 WPF 应用程序中处理窗口消息
【发布时间】:2014-05-29 10:20:11
【问题描述】:

我在 WPF Dispatcher 机制中发现了一些奇怪的行为。让我快速解释一下应用程序:

我有一个 WPF 窗口,其中包含多个托管在 WindowsFormsHosts 中的 OpenTK OpenGLControls。在 OpenGLControl 的 OnPaint 事件期间,我会渲染相应的 3D 场景。

在渲染过程中,我可能需要等待另一个线程完成。现在的问题是,在调用 Thread.Join() 期间,无论出于何种原因,Dispatcher 都会处理其他窗口消息。这导致我的应用程序出现问题,我想禁用/阻止/了解该行为。你知道这是怎么可能的吗?

在我的应用程序中,这会导致意外的 OpenGL 上下文切换,因为在处理另一个 OpenGL 控件的绘制事件时会处理不同的 OpenGL 上下文的绘制事件。

这是应用程序的调用堆栈,也许这有帮助: Callstack http://public.virtualmischa.de/bugs/paintevent-while-join.png

谢谢

迈克尔

【问题讨论】:

  • 据我了解,您的问题是调度程序在您等待 Thread.Join() 时继续处理消息?
  • 是的,完全正确。还有什么方法可以防止吗?

标签: c# wpf multithreading opengl


【解决方案1】:

Thread.Join is knownWaitHandle.WaitOne 通常发送更多消息。

代替:

_thread.Join();

试试这个:

Task.Run(() => _thread.Join()).Wait();

这会将_thread.Join() 从 UI 线程移动到 ThreadPool 线程,在该线程中没有可抽的东西。它应该防止在 UI 线程上运行。

也可以使用超时:

Task.Run(() => _thread.Join(timeout)).Wait();

【讨论】:

  • 好的,谢谢您的回答。不幸的是,我不能强制我的应用程序使用 MTAThread 属性,因为我正在使用 Winforms。我讨厌所有这些魔法......所以我也需要使用不同的锁定机制,或者用 Task.Run(() => {}).Wait() 围绕每个锁定操作。很烦人。
  • @BikingGlobetrotter,这里不需要MTAThread。具体是什么不适用于此解决方案?
  • 实际上,我想避免使用您的 sn-p,对我来说,这看起来像是一种解决方法,这就是我想使用 MTAThread 的原因。这种行为有两个后果: 1. 我需要解决我们库函数中使用 lock(this){} 的每个锁,因为 Monitor.TryEnter 也会受到这种行为的影响 2. 任何使用 lock(this){} 的代码} / Thread.Join 假设在单线程环境中工作需要检查。该行为导致隐藏的多线程
  • @BikingGlobetrotter,我不确定我是否遵循,也许是因为我对您的应用程序的线程模型没有清晰的了解。您不能在 MTA 线程上使用 WinForms/WPF/Graphics API。我不确定 OpenTK /OpenGL,但我认为它们也需要 STA 线程。如果从 STA 线程调用,Thread.Join 进行抽水。如果你想阻止抽水,你必须从非 STA 线程调用Thread.Join,如上所述。
猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多