【发布时间】:2009-06-03 19:40:30
【问题描述】:
当 UI 线程等待 WaitHandle 或其他线程原语时,有什么方法可以处理所有 Windows 消息?
我意识到它可能会产生非常混乱的重入问题;反正我也想做。
EDIT:等待发生在必须在 UI 线程上运行的复杂函数的中间。因此,将等待移至后台线程不是一种选择。 (将函数一分为二会造成复杂且无法维护的混乱)
【问题讨论】:
标签: c# .net multithreading waithandle message-loop
当 UI 线程等待 WaitHandle 或其他线程原语时,有什么方法可以处理所有 Windows 消息?
我意识到它可能会产生非常混乱的重入问题;反正我也想做。
EDIT:等待发生在必须在 UI 线程上运行的复杂函数的中间。因此,将等待移至后台线程不是一种选择。 (将函数一分为二会造成复杂且无法维护的混乱)
【问题讨论】:
标签: c# .net multithreading waithandle message-loop
我会在单独的后台线程中运行整个“不能拆分的复杂功能”,并让它仅在需要时向 GUI 报告(使用 Invoke/BeginInvoke 方法一个控制)。
在更增强的版本中,您应该在不依赖 UI 且更易于单元测试的非 UI 控制器中运行复杂的功能。回调 UI 并在 UI 中显示结果,可以通过让 UI 订阅控制器提供的事件来轻松实现。
【讨论】:
您为什么不直接生成另一个线程来等待,并让他在适当的时刻通过消息(或其他方式)通知 UI 线程?
这是在阻塞事件期间允许 UI 线程消息处理的常用方法。
编辑: 我现在明白了——你在 UI 代码中内置了应用程序逻辑逻辑。那么,这确实是一个设计问题。从长远来看,您最好将该功能从 UI 拆分为一个独立的对象,并使用某种机制与您的工作人员的 UI 进行状态通信。
除了让您的 UI 代码专注于 UI 的好处之外,这还允许您单独对逻辑代码进行单元测试。
【讨论】:
不确定 C#,但在普通的 Win32 编程中,您可以使用 MsgWaitFor...() 函数之一进行实际等待。它会在消息队列中出现消息时以及正在等待的对象何时发出信号时通知您。如果它报告消息存在,您可以调用 GetMessage()、TranslateMessage() 和 DispatchMessage() 来处理消息,然后返回等待。
【讨论】:
我通常建议将您的等待条件放在另一个线程上。
但是,话虽如此,您始终可以在任何时候调用Application.DoEvents 来处理消息泵,包括在等待句柄上“等待”时(只是超时、执行事件、超时等待等,直到您得到“通过”等待句柄)。
【讨论】: