Application.Run(Form)vs. Form.Show()?

时间:2011-03-04 23:10:40

标签: c# winforms multithreading

假设主GUI线程上发生了很多事情(数据流入,用户操作等)。假设我们想创建一个表单并显示它。

如果我们使用Application.Run(Form)而不是Form.Show(),是否可以提升效果?有一个更好的方法吗?请解释原因或原因。

2 个答案:

答案 0 :(得分:13)

除非您知道它的作用,否则请勿使用Application.Run()。而且,一旦你知道它做了什么,你就会知道为什么你不应该使用它,除非在程序开始时。

Application.Run启动消息泵。这是任何GUI程序的核心,它使窗口能够接收消息,从而允许它触发事件并执行操作。你不能有两个消息泵,因为这没有任何意义。

(是的,我知道你可以有两个消息泵,但你为什么要这么做呢?一个泵很难!)

至于你的真正的问题(我怎么不在我的GUI线程上做东西),这有点复杂。最简单的答案是“使用线程”。由于我不知道你的情况,我只能给出一些一般的建议:

  1. 不要尝试操纵其他线程的控件。充其量,它将无法正常工作。在最坏的情况下,它会让你的房子着火(好吧,也许不是那么糟糕。但是,不要这样做。)。相反,您需要Invoke方法。下面将提供一个示例。

  2. 不要在GUI线程上运行长时间运行的进程。简短的事情是可以的,但任何可能需要超过半秒的事情都可能最好卸载到另一个线程。

  3. 使用事件从您的工作线程回传到您的GUI线程。

  4. 以下是如何运行工作线程的示例:

    delegate void VoidDelegate();
    
    List<int> results;
    bool cancelWork = false;
    
    void DoWork() {
        int calc;
        results = new List<int>();
    
        for(int i = int.MinValue ; i < int.MaxValue; i+=10) {
            if(cancelWork) break;
            results.Add(i);
        }
    
        this.Invoke(new VoidDelegate(WorkFinished));
    }
    
    void Button1_Click(object sender, EventArgs e) {
        button1.Enabled = false;
        button2.Enabled = true;
        cancelWork = false;
        Thread t = new Thread(DoWork);
        t.Start();
    }
    
    void Button2_Click(object sender, EventArgs e) {
        button2.Enabled = false;
        cancelWork = true;
    }
    
    void WorkFinished() {
        button1.Enabled = true;
        button2.Enabled = false;
        textBox1.Text = results.Count.ToString();
    }
    

    显然,这是一个人为的例子,但它符合我的目的。

    此假设表单包含两个按钮button1(“运行”)和button2(“取消”),以及一个文本框textbox1。 button2应该开始禁用(Enabled = false)。

    当工作线程运行时,用户可以与任何其他控件交互,包括“取消”按钮(在我的示例中为button2)。完成后,Invoke WorkFinished函数显示结果(以及清除状态)。

答案 1 :(得分:5)

如果您指的是您应用的主要表单,那么答案就是否定的。 Application.Run()初始化主消息循环,应该在应用程序启动时调用一次。应用程序生命周期内显示的所有其他表单应为Form.Show或等效形式。

您可以从另一个线程调用Application.Run,​​但是无论如何您都需要两个UI线程进行同步。你不能只是传递东西而不确保你不会陷入争用的情况。