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

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).


If you're referring to something that is not your app's main form then the answer would be no. Application.Run() initializes the main message loop and should be called just once when the application starts. All other forms shown during the lifetime of the app should be Form.Show or equivalent.

You can call Application.Run from another thread, but then you'll have two UI threads you need to synchronize anyway. You can't just pass stuff around without ensuring that you won't get into a contention situation.