首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这是如何实现的:在WaitOne中处理OnPaint

这是如何实现的:在WaitOne中处理OnPaint
EN

Stack Overflow用户
提问于 2010-12-28 00:47:09
回答 2查看 2.1K关注 0票数 20

我有一台ManualResetEvent。有一次,我使用WaitOne等待该事件。令我惊讶的是,我在WaitOne中收到了一个OnPaint事件。这种情况也经常发生。

堆栈跟踪如下所示:

我知道WaitOne会阻塞当前线程,并且在事件触发之前不允许执行任何其他代码。

有人能解释一下这里发生了什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-12-28 02:09:15

这是设计好的。CLR遵守单线程单元(STA)的合同。图形用户界面应用程序的主线程是STA正如Windows编程中所要求的,Main()方法上的STAThread属性确保。

STA线程的硬规则是它必须抽出一个消息循环(如Application.Run),并且永远不能阻塞。当后台线程使用任何COM单元线程对象时,阻塞STA线程极有可能导致死锁。它们有很多,剪贴板和WebBrowser是你在.NET程序中会遇到的常见工具。还有许多不太显眼的,可以作为.NET包装器类使用。

当您使用LOCK语句或调用同步类的Wait方法时,CLR通过执行消息循环来确保阻塞不会导致死锁。或Thread.Join()。该消息循环调度WM_PAINT消息,导致Paint事件运行。

您需要重新构建您的程序,以确保这不会造成问题。非常重要的是要专注于根本不阻塞主线程。当您有BackgroundWorker类或Control.BeginInvoke()可供使用时,很少需要它。出于某种奇怪的原因,Mutex类不做这种抽运,这可能是另一种方式。尽管如果你这样做,死锁就会潜伏在角落里。

票数 24
EN

Stack Overflow用户

发布于 2010-12-28 01:05:46

我在lock()语句中也看到了这种行为。显然,.net框架线程类在等待UI线程上的锁时会启动一个消息循环。这只是解释了正在发生的事情。原因可能是为了防止在使用旧的STA COM对象时出现死锁。我不知道有什么方法可以防止这种情况发生。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4540244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档