3

I want to do some initialization of various things at runtime of my WinForms application. I'm looking specifically at the Program.cs file that every WinForm application has. In it, I see:

[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new frmMain());
}

I know that this is what starts up the application and creates the initial form (in my case, an instance of frmMain).

Can I not just put my initialization code before Application.Run()? The initialization I need to do is to check a few registry entries, create them if necessary, and connect to a database. Will any feature not be available to my instantiation code if I put it before Application.Run()?

Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
  • 1
    I've performed database operations before `Application.Run(form)` without harm. – BoltClock Apr 23 '11 at 20:23
  • That's good news! I have a little form I use as a progress indicator. This form will be the first thing the user sees, as the application is starting up. Usually what I would do is create an invisible form that is the first to load. This form then in turn creates the generic progress form and does the loading. But, initialization in `Program.cs` is much better. Thanks! – Chris Laplante Apr 23 '11 at 20:27

5 Answers5

4

Application.Run() starts message loop for your main thread. SO before that line of code you can do anything except what is dependent on windows messages (click, keyup, ...)

Xaqron
  • 29,931
  • 42
  • 140
  • 205
3

A Windows Forms application starts when the Main method is called. You can implement initialization procedures on the Main function. However, to initialize a Windows Forms application fully and start it routing Windows Forms events, you need to invoke Application.Run.


Read about Application

Akram Shahda
  • 14,655
  • 4
  • 45
  • 65
  • 1
    Aha! I can call `Application.Run()` without a form or context as a parameter. Then, I can perform initialization. Doing this after the call to `Run` allows forms that I create during initialization to be interacted with, if necessary. Finally, I can manually create my main form and display it. – Chris Laplante Apr 23 '11 at 20:38
  • 1
    In this way even if you closed your main form, your application will still running until you explicitly call Application.Exit() – Akram Shahda Apr 23 '11 at 20:43
  • Oh, then maybe I should just stick with initializing before `Application.Run()`... either way, I'll have to experiment. – Chris Laplante Apr 23 '11 at 20:46
3

Yes, no problem, the code in Main() is boilerplate but not cast in stone.

Do keep in mind that any code you run before calling Application.Run() will delay the startup of your user interface. Once that goes over a second or two, give or take, you might want to consider displaying a splash screen so that the user gets some visual feedback that your program got started. Well supported by the .NET framework, check this answer.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Good point, thanks. I'll create a splash screen, or maybe just use my progress dialog, in conjunction with my comment under Akram Shahda's answer. – Chris Laplante Apr 23 '11 at 20:40
2

One important thing you don't have available before Run is a valid SynchronizationContext.Current. So if you use any kind of event-based asynchronous pattern components, they'll seem to work just fine, but will fire their events on a thread pool thread instead of the GUI thread.

Because of this, any asynchronous startup code that queues completion events to the GUI should be started from an event, not before Run.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
1

As long as you don't need to access anything declared in frmMain you should be OK.

However the MSDN states:

Begins running a standard application message loop on the current thread.

so you won't have access to the message loop.

There is another overload Application.Run(ApplicationContext) that will let you execute code before your form is displayed - this appears to be the way to go.

The example code on this page does some initialisation before showing two forms, so you should be OK with your model.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • Interesting. What if I created a new instance of frmMain in my initialization code, and then passed it to `Application.Run()`? – Chris Laplante Apr 23 '11 at 20:32
  • @SimpleCoder - I think you can do that. Not tried it myself though. – ChrisF Apr 23 '11 at 20:35
  • Just tried it, and it worked. The only problem with this approach is that I can't cleanly exit the application if an error occurs. `Application.Exit()` doesn't work, because `Run` hasn't been called yet. I think creating my own `ApplicationContext` class is the way to go. Thank you! – Chris Laplante Apr 23 '11 at 20:36
  • Found that I can use `Environment.Exit(0)` in place of `Application.Run()`. – Chris Laplante Apr 23 '11 at 20:47