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.
Show() method shows a windows form in a non-modal state. ShowDialog() method shows a window in a modal state and stops execution of the calling context until a result is returned from the windows form open by the method.
Run() Begins running a standard application message loop on the current thread, without a form. Run(ApplicationContext) Begins running a standard application message loop on the current thread, with an ApplicationContext.
Winforms and Windows Forms are the same thing. Winforms is the shortened name for Windows Forms.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With