【问题标题】:Application.DoEvents() called constantly while application is running?Application.DoEvents() 在应用程序运行时不断调用?
【发布时间】: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()。我很难相信这对应用程序来说是一件好事。我很想听听对此的其他意见。谢谢。

【问题讨论】:

    标签: .net-3.5 windows-mobile compact-framework


    【解决方案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。我可能会重写该方法以使用 lockfinally 块来调用 Monitor.Exit。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-24
      • 2021-11-29
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      • 1970-01-01
      • 2017-09-25
      相关资源
      最近更新 更多