Application.DoEvents() 在应用程序运行时不断调用?
Posted
技术标签:
【中文标题】Application.DoEvents() 在应用程序运行时不断调用?【英文标题】:Application.DoEvents() called constantly while application is running? 【发布时间】:2011-07-14 11:14:52 【问题描述】:我试图为我的应用程序添加一个表单兑现模块,我实现了这个 msdn 示例:Form Stacking and Caching
对于那些无法下载示例的人,这是包含我所指代码的类:
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Threading;
namespace GUIFramework
public class FormStack : CollectionBase
private System.Collections.ArrayList stack = new ArrayList();
public void Run()
do
System.Windows.Forms.Application.DoEvents();
while(List.Count > 0);
public void Stop()
// nicely destroy each Form
foreach(StackForm sf in List)
sf.Dispose();
// clear the list to kill the message pump in Run()
List.Clear();
public void Push(Type FormType)
// only allow 1 Push at a time to maintain cache and stack itegrity
Monitor.Enter(this);
foreach(StackForm sf in List)
if(sf.GetType().Name.Equals(FormType.Name))
// form is cached so display cached version
sf.Visible = true;
// add it to the stack
stack.Add(FormType.Name);
return;
// the Form wasn't cached, so create it
StackForm form = Preload(FormType);
// display it
form.Visible = true;
// add a close event handler
form.FormClosed += new FormClose(form_FormClosed);
// add it to the stack
stack.Add(FormType.Name);
Monitor.Exit(this);
public StackForm Preload(Type FormType)
StackForm form = (StackForm)Activator.CreateInstance(FormType);
// get data on a separate thread
form.LoadData();
// build the form
form.InitializeComponent();
// wait for the data thread to finish
form.threadRunning.WaitOne();
// now populate the controls with any retrieved data
form.Populate();
form.MinimizeBox = false; // required to get close event on PPC!
// add it to the cache
List.Add(form);
return form;
public void Pop(uint FormsToPop)
if(stack.Count <= FormsToPop)
throw new Exception("You cannot Pop the entire stack!");
else
// remove from stack but not cache
for(int i = 0 ; i < FormsToPop ; i++)
stack.RemoveAt(stack.Count - 1);
foreach(StackForm sf in List)
// find the last form in the stack
if(sf.GetType().Name.Equals(stack[stack.Count - 1]))
// make it visible
sf.Visible = true;
private void form_FormClosed()
Pop(1);
public override string ToString()
string message = "There are " + List.Count.ToString() + " forms cached\r\n";
message += "Stack contents:";
for(int i = stack.Count - 1 ; i >= 0 ; i--)
message += "\r\n" + stack[i].ToString();
return message;
Run()
方法在应用程序运行时不断调用Application.DoEvents()
。我很难相信这对应用程序来说是一件好事。我很想听听对此的其他意见。谢谢。
【问题讨论】:
【参考方案1】:首先,您需要了解 WinForms 应用程序的一般工作原理。 Application.Run 调用的深处是一段代码,通常称为消息泵。这是一个调用 GetMessage、TranslateMessage 和 DispatchMessage 的无限循环。本质上,Application.DoEvents 调用该循环的一次循环。您正在查看的 DoEvents 循环只是执行此操作。
现在为什么,确切地说,甚至需要那个电话,我不能老实说。这很糟糕,因为我编写了代码,但在我的辩护中,这段代码已经有将近十年的历史了,我几乎不记得我上周做了什么。
如果删除循环,会发生什么?我没有看到任何表明您会得到绘图工件或绘图失败(这是添加调用的典型原因)的任何内容,但此代码也是针对 CF 1.0 编写的,因此很可能是为了克服运行时限制。
对于它的价值,我 revisited and rewrote the code in 2009 并且重写没有循环(甚至没有 Run 方法)。
顺便说一句,我看到 Push 中有一个错误。 foreach 循环有一个return
而没有执行 Monitor.Exit。我可能会重写该方法以使用 lock
或 finally
块来调用 Monitor.Exit。
【讨论】:
以上是关于Application.DoEvents() 在应用程序运行时不断调用?的主要内容,如果未能解决你的问题,请参考以下文章
什么相当于 WPF 应用程序中的 Application.DoEvents()
WPF 中的 Application.DoEvents() 在哪里?
Application.DoEvents() 在应用程序运行时不断调用?
与 Application.DoEvents() 和 PictureBox 混淆 [重复]