简体   繁体   中英

Show a splash screen at once

We are dealing with slow start for WinForm applications (it is a large application and has many control assemblies). Control assemblies are DevComponents. Ngen was applied to prevent jit compilation, but the loading time just decreased a little.

The app has a splash screen, but it appears only in 12 seconds after the app has started. Is there any approach to show the splash screen at once?

Our current suggestion is to create a lightweight app with the splash screen, run the main app in a separate process, and close the lightweight app when initialization of the main app is done.

You're never going to get a splash screen for a .NET application to show instantly . Even if you've NGen'ed the assemblies to eliminate the JIT-compile time, you still have to wait while all of the .NET Framework DLLs are loaded into memory. It's a pretty large framework, and it takes a non-trivial amount of time to load upon a cold start. Nothing you can really do about that.

Microsoft has tried to ease the pain as much as possible. The WindowsFormsApplicationBase class (it's defined in the Microsoft.VisualBasic namespace, but don't let that scare you off; it's perfectly usable from a C# application) provides a built-in mechanism for showing a splash screen. All you have to do is set its SplashScreen property to the appropriate form, and everything else is handled behind the scenes. It's been heavily optimized for maximum response time, even in a cold-start situation, but it's still not going to be instant .

The only other option that you have is to write small wrapper in unmanaged code, whose only purpose is to throw the splash screen up as quickly as possible, then call your .NET application to start launching itself. The lighter the better here, of course. C++ is an option, but C is probably a better option. You need to minimize the number of external libraries that you have to link, so a framework like MFC or Qt is definitely out: you need to target the Windows API directly.

The Visual Studio team did something similar in VS 2010. They have a pretty interesting explanation of the process available on their blog :

Even though Visual Studio 2010 uses WPF for its main window, using WPF for the splash screen would require that we wait for the CLR and WPF to initialize before we could paint a single pixel on the screen. While we've made some tremendous improvements in CLR and WPF startup speed in .Net 4.0, it still can't quite match the performance of raw Win32. So, the choice was made to stay with native C++ code and Win32 for the splash screen.

But I wouldn't spend too much time here. Since you should generally give users the option to turn splash screens on and off, and most users will opt to turn it off, it's unlikely that very many people will ever see it in the first place. Any good optimization profiler would tell you that it isn't worth optimizing.

For a lightweight, reusable splash screen component written in C++ and using the native Windows APIs, see Stefan Olson's splash screen . It takes the approach Cody Gray alludes to of starting with a separate non-CLR process which then loads the main CLR app.

I had to implement the exact same thing at my last job and I can confirm the approach works well -- the time between the user clicking the program icon in the start menu and the splash screen appearing is just a few milliseconds and so feels 'instant'.

I'd say go along with your current suggestion.

The Winforms app will not show unless it has loaded completely into the memory, and since it takes time, I'd suggest having a loader application which shows the splash and executes the main huge app(as a child process).

In the huge app, terminate the parent app upon load. That won't kill the child, BTW.

The quick and dirty way that I have done in the past is to have two applications, your main application and your splashscreen application. The main application is normal with all of its heavyweight DLLs, controls, etc. The splashscreen application is simply an application and one Windows form, with all of the unneccesary reference DLLs stripped from the project - in fact you can take this one step further and make use a lighter weight .NET framework like the compact .NET framework or an earlier version of the .NET framework like 1.X or 2.0.

What you would do is have the splashscreen application startup and immediately show the single splashscreen. Have a Windows form timer (set for say 100 ms) and enable the timer as the last line of the form's Load event. When the timer fires, disable the timer and then launch your real application. See this discussion for how to do that. Now the main application will begin to fire up. Once the application is done with its initialization and perhaps loading the first form, then have the main application kill the splash screen application. More info on killing an application here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM