有没有办法在抽取窗口消息时等待线程完成处理?

时间:2014-09-09 19:56:23

标签: c# .net vb.net multithreading

我试图在GUI线程上使用AutoResetEvent.WaitOne(),希望它不会完全阻止GUI线程并允许GUI线程在等待信号时保持抽取窗口消息(类似于Thread.Wait( ))。我了解到这不是一个正确的假设。

所以我正在寻找一种方法来使用GUI Thread并等待线程完成运行(类似于使用AutoResetEvent.WaitOne())但保持消息流动。 (请不要DoEvents())

我想简短的问题是:在.NET中是否存在等待窗口消息(尤其是“Paint”事件)的WAIT?

2 个答案:

答案 0 :(得分:4)

CLR有一个特殊的解决方法,用于在STA线程上调用WaitOne()。那是非法,不允许阻止支持公寓线程的线程。这很容易造成僵局。实际上,CLR将开始接管泵送消息的职责,大致类似于MsgWaitForMultipleObjects。非常粗略。

虽然这可以使UI线程的基本管道保持活动状态like painting,但如果您可以避免它,那么这不是您想要做的事情。古怪的东西可能发生,与使用Application.DoEvents()完全不同,尽管CLR代码确实试图最小化重入所造成的损害。

他们是如何做到这一点的秘密,它是故意从SSCLI20发行版中省略的,否则这是CLR代码的一个非常完整的副本。克里斯布鲁姆blogged about it,以他惯常的方式非常难以理解,但只是挥手而不泄露任何好的秘密。代码本身对逆向工程非常有抵抗力,它是 large 。它的唯一常见迹象是从程序员的堆栈轨迹中找回它,这是一个非常难以解决的问题。

换句话说,您正在调用一个高度无证且难以理解的代码路径。不要这样做。从根本上说,根本没有必要,您可以随时调用UI线程并继续使用您在WaitOne()调用之后获得的代码。这很安全。

答案 1 :(得分:0)

我不知道你要求的任何东西。 AFIK(据我所知),你需要启动第二个后台任务或线程等待AutoResetEvent在后台线程和你的UI线程中触发,一旦你启动任务或第二个线程,退出你的方法所以你可以随意做“消息抽”的工作。

因此,在这种情况下,后台线程需要在触发AutoResetEvent以继续处理后完成处理。