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:
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.
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.
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 Invoke
s the WorkFinished
function, which displays the results (and otherwise cleans up state).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…