如何可能:在WaitOne中处理OnPaint [英] How is this possible: OnPaint processed while in WaitOne

查看:116
本文介绍了如何可能:在WaitOne中处理OnPaint的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ManualResetEvent 。有一点,我使用 WaitOne 等待该事件。令人惊讶的是,我在 WaitOne 中收到一个 OnPaint 事件。

I have a ManualResetEvent. At one point, I wait on that event using WaitOne. To my amazement, I received an OnPaint event while in the WaitOne. This happens quite often too.

堆栈跟踪如下所示:

我了解到一个 WaitOne 将阻止当前线程,并且不会允许在事件触发之前执行任何其他代码。

I understood that a WaitOne would block the current thread and would not allow any other code to be executed until the event fires.

有人可以解释这里发生了什么吗?

Could someone explain what happens here?

推荐答案

这是按设计。 CLR荣获单线公寓(STA)的合同。 GUI应用程序的主线程是Windows编程中需要的STA,Main()方法中的[STAThread]属性可以确保。

This is by design. The CLR honors the contract of a single-threaded apartment (STA). The main thread of a GUI app is STA as is required in Windows programming, the [STAThread] attribute on the Main() method ensures that.

STA的硬规则线程是必须泵送消息循环(如Application.Run),永远不会阻止。当后台线程使用任何COM公寓线程对象时,阻止STA线程很可能导致死锁。其中有很多,剪贴板和WebBrowser是您在.NET程序中遇到的常见问题。许多不太可见的,也可以作为.NET包装器类使用。

Hard rules for an STA thread are that it must pump a message loop (like Application.Run) and can never block. Blocking an STA thread is highly likely to cause deadlock when background threads use any COM apartment threaded objects. There are many of them, the clipboard and WebBrowser are common ones you'll encounter in a .NET program. Many less visible ones as well, available as .NET wrapper classes.

CLR确保在使用锁定语句时通过抽取消息循环来阻止死锁,调用同步类的Wait方法。或者Thread.Join()。该消息循环调度WM_PAINT消息,导致Paint事件运行。

The CLR ensures blocking can't cause deadlock by pumping a message loop when you use the lock statement or call the Wait method of the synchronization classes. Or Thread.Join(). That message loop dispatches the WM_PAINT message, causing the Paint event to run.

您需要重新构建程序,以确保不会导致问题。非常重要的是专注于不阻塞主线程。当您使用BackgroundWorker类或Control.BeginInvoke()时,这是非常少见的。对于某种奇怪的原因,Mutex课不会这样做,这可能是另一种方式。如果你这样做,虽然死锁潜伏在拐角处。

You need to restructure your program to ensure this doesn't cause a problem. Pretty important to focus on not blocking the main thread at all. It is very rarely needed when you have, say, the BackgroundWorker class or Control.BeginInvoke() at your disposal. For some kind of odd reason the Mutex class doesn't do this kind of pumping, that could be another way. Although deadlock is lurking around the corner if you do.

这篇关于如何可能:在WaitOne中处理OnPaint的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆