Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Suppose a lot of stuff is happening on the main GUI thread (data flowing in, user actions, etc.). Suppose we would like to create a form and show it.

Could there be a performance boost if we use Application.Run(Form) as opposed to Form.Show()? Is there a better way to do this? Please explain why or why not.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
189 views
Welcome To Ask or Share your Answers For Others

1 Answer

Do not use Application.Run() unless you know what it does. And, once you know what it does, you'll know why you shouldn't use it except at the beginning of the program.

Application.Run starts a message pump. This is the heart of any GUI program, and what enables the window to recieve messages, which allows it to fire events and do stuff. You cannot have two message pumps, as that doesn't make any sense.

(Yes, I know that you can have two message pumps, but why would you ever want to? It's hard enough having one pump!)

As to your real question (how do I not do stuff on my GUI thread), that's a bit more complicated. The simplest answer is "use threads". since I don't know the particulars of your situation, I can only give some general advice:

  1. Do not try to manipulate controls from other threads. At best, it won't work. At worst, it will set your house on fire (okay, maybe not that bad. But, don't do it.). Instead, you need to Invoke methods. An example will be provided below.

  2. Do not run long running processes on your GUI thread. Short things are okay, but anything that might take longer than half a second are probably best offloaded to another thread.

  3. Use events to communicate from your Worker thread back to your GUI thread.

Here is an example of how to run a worker thread:

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();
}

Obviously, this is a contrived example, however it serves my purpose.

This hypothetical form contains two buttons, button1 ("Run") and button2 ("Cancel"), and a text box, textbox1. button2 should start out disabled (Enabled = false).

While the worker thread it running, the user can interact with any other controls, including the "Cancel" button (button2 in my example). Once it finishes, it Invokes the WorkFinished function, which displays the results (and otherwise cleans up state).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...