在后台线程上调用Application.DoEvents()有什么效果?

问题描述 投票:0回答:2

正如问题所问:在后台线程上调用 Application.DoEvents() 时会做什么?

为了提供一些背景信息,我正在回顾一个用 C# 为 .NET CF 编写的(不是我自己)相当复杂的解决方案。我审查它的原因是它有一些固有的问题,我被要求调查这些问题。

一个相当有趣的花絮是应用程序在启动时创建一个长时间运行的后台线程,该线程进入定时循环。它最终会在每次循环迭代时调用 Application.DoEvents()。

我不太清楚这会产生什么影响 - 它会刷新应用程序主线程上的消息队列吗?或者它是否刷新调用它的线程上的消息队列(即使后台线程没有要刷新的队列)。

这几乎肯定是导致一些无法解释的应用程序行为的原因。

c# multithreading .net-cf-3.5
2个回答
4
投票

Application.DoEvents() 处理当前消息队列中的所有 Windows 消息,每个创建窗口的线程都会处理一个消息。因此,如果您在“后台线程”上调用它,它不会执行任何操作,除非您在该线程上创建了一个窗口。


0
投票

它将一直工作,直到您的主 Ui 线程调用 ShowDialog,并且在显示对话框后,并且仍然显示您从后台线程调用 Application.DoEvents。

当您在主 UI 线程上调用 ShowDialog() 时,它会打开一个等待用户输入的模式对话框。 当对话框打开时,主 UI 线程实际上被阻塞,直到对话框关闭。如果您同时从后台线程调用 Application.DoEvents(),则后台线程和主 UI 线程之间可能存在争用或死锁,导致后台线程显示为锁定。

==> 我在实际项目中也遇到过这种情况。 发现它的一种方法是重现该场景,一旦使用调试器阻止中断并查看不同的线程和调用堆栈,您应该在一个线程中看到 ShowDialog() ,在另一个线程中看到对 Application.DoEvents() 的调用Visual Studio 会轻轻地隐藏您并与您交换:

System.Windows.Forms.Application.ThreadContext.RunMessageLoop()

© www.soinside.com 2019 - 2024. All rights reserved.