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

kli*_*iao 7 c# multithreading winforms

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

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

Mik*_*ron 13

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

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

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

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

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

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

  3. 使用事件从Worker线程回传到GUI线程.

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

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();
}
Run Code Online (Sandbox Code Playgroud)

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

这个假设形式包含两个按钮button1("运行")和button2("取消"),以及一个文本框textbox1.button2应该从禁用(Enabled = false)开始.

当工作线程运行时,用户可以与任何其他控件交互,包括"取消"按钮(button2在我的示例中).一旦完成,它Invoke就是WorkFinished功能,它显示结果(否则清理状态).


kpr*_*bst 5

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

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