WPF performance and .NET Framework Client Profile related blogs provided by Jossef Goldberg.
To improve the perception of a more responsive startup experience many WPF applications added a Splash Screen to their startup. The Splash Screen, which does not load WPF code shows as soon as possible and is displayed until the application main window is rendered. Up until 3.5 Sp1 we pointed developers to sample code available on this blog. In the just released .Net 3.5 SP1 we added basic Splash Screen support and new APIs and we recommend that you take advantage of it. (See download locations below)
A Visual Studio 2008 Sp1 Item Template that makes adding a Splash Screen much easier is available on WPF Futures site on www.codeplex.com/wpf.
How to Use:
The easiest way to add is by using VS 2008 SP1. · Create a new Standalone VB or C# WPF project in VS 2008 Sp1. Verify “Target Framework” project property is “.Net Framework 3.5”
· Add an image (your splash screen image) to the project (e.g. by drag and drop)
· Set the image BuildAction to SplashScreen
· Do F5 ( Build+Run), splash screen should be shown.
· To disable the Splash Screen image functionality you can either:
o Remove the “SplashScreen.png” image from the project, or
o Set the splash image BuildAction to ‘None’.
Upon compile, the build (PresentationBuildTasks.dll) will generates below code in App.g.cs:
1: SplashScreen splashScreen = new SplashScreen("Splashscreen1.png");
3: MyApp.App app = new MyApp.App();
Note: Above code will be generated in VS 2008 Sp1 only if the “Target Framework” project property is “.Net Framework 3.5”. Otherwise no code will be generated.
Install the Splash Screen Visual Studio 2008 Sp1 Item Template from the WPF Futures site.
· Create a new Standalone VB or C# WPF project in VS 2008 Sp1. Verify “Target Framework” project property is “.Net Framework 3.5”
· In VS, Right-Click on your Project and then select “Add / New Item… / Splash Screen (WPF)”.
· Notice the new image BuildAction is set to SplashScreen for you.
· Do F5 (Build+Run), the default splash screen image that was installed with the template will be shown (you likely want to replace with your own Splash Screen image)
Another approach is to directly use the new public Splash Screen APIs. With this approach you can set the ‘BuildAction=Resource’.
For example you can call the following code:
1: SplashScreen appSplash = new SplashScreen("Splashscreen1.png");
3: //….do some work…
4: appSplash.Close( TimeSpan.FromSeconds(0.3)); // Splash to fadeout in 300ms
The WPF Splash Screen APIs are defined as below:
1: namespace System.Windows
3: public class SplashScreen
5: public SplashScreen(string resourceName);
6: public SplashScreen(Assembly resourceAssembly, string resourceName);
7: public void Show(bool autoClose);
8: public void Close(TimeSpan fadeOutDuration);
public ApplicationSplashScreen(string resourceName)
Constructor. resourceName points to the embedded splash image
public ApplicationSplashScreen(Assembly resourceAssembly, string resourceName)
Constructor. resourceAssembly specify the assembly in which resources lives resourceName points to the embedded splash image
public void Show(bool autoClose);
Constructor. Shows the splash image.
If autoClose is true, the code uses the dispatcher to queue an item at Idle priority, enabling the Splash screen to start fading out using the default fadeOutDuration (300 msec) after the application first renders.
If autoClose is false, the app is responsible to call Close(fadeOutDuration), in this case the splash screen fades out using the provided fadeOutDuration.
IOException if resource provided in constructor not found in app assembly
public void Close(TimeSpan fadeOutDuration)
Closes the splash window.
fadeOutDuration is the time for splash screen to fade out. If autoClose is true, WPF will close the window and use a 300 msec as the default fadeOutDuration.
It is important to understand that the Splash Screen has the following limitations:
· It does not actually improve application cold startup time.
· Cannot display sequence of splash images or animation.
· Does not support for animated GIFs
· Does not support earlier versions of VS (earlier than VS2008 Sp1). You should still be able to use the APIs (e.g. Approach C)
· Does not support XBAPs (XBAPs already have their own improved coldstart progress page in .Net 3.5 Sp1)
· Does not have XAML support for setting splash screen image
· Expression Blend does not provide UI to set the SplashScreen build action
Visual Studio 2008 Express Editions with Service Pack 1 (Bootstrappers)
Visual Studio 2008 Express Editions with Service Pack 1 (iso)
Visual Studio 2008 Service Pack 1 (Bootstrapper)
Visual Studio 2008 Service Pack 1 (iso)
Visual Studio Team System 2008 Team Foundation Server Service Pack 1
.NET Framework 3.5 Service Pack 1
PingBack from http://blog.a-foton.ru/2008/08/what%e2%80%99s-new-in-wpf-35-sp1-splash-screen-to-improve-perceived-startup-perf/
Hi Josef, for the "Does not support earlier versions of VS" caveat, isn't it just for Approach A?
The Splashscreen feature was part of SP1. However, there was no VS template to get it done fast. We have
WRT "Does not support earlier versions of VS" caveat. Yes, you should still be able to use the SplashScreen APIs (e.g. Approach C)
Le démarrage des applications .NET et notamment WPF surtout à froid peut parfois être un problème car
Thank you very much for a thorough description of how to use the Splashscreen!
I have tried using Approach A and Approach C, and in both instances my application sometimes throws a Win32Exception on the Close(timeSpan) method if I switch focus from my app to another app while it is loading.
This sometimes happens to me, for instance, if I go back to Visual Studio during a debug session, or when I answer OneCare's question about allowing my app to access the internet. Here is the top of the exception's stack trace:
Unhandled Exception in application AppDomain: System.ComponentModel.Win32Exception: The operation completed successfully
at MS.Win32.UnsafeNativeMethods.SetActiveWindow(HandleRef hWnd)
at System.Windows.SplashScreen.Close(TimeSpan fadeoutDuration)
... could I trouble you for any advice for how to resolve this?
I am working around the issue for now by using Approach C, and my call to Close(timeSpan) is wrapped in a try/catch block to get the Win32Exception. If the exception is thrown, I try again to close the SplashScreen whenever my application's main window is activated.
to robburke :
I was wondering, are you closing the SpalshScreen Window from another thread (you should close it from the UI thread) ?
Do you see this on XP & Vista?
Can you send me a little sample with the repro ?
I'm having the same problem as robburke.
The exception comes now and then, maybe once every 10 startups.
I used approach A), now I'm testing with C).
I'm also having the same problem as robburke.
This is on Vista.
I'm using the API with an AutoClose. I'm also forcing a single instance of my App, not sure if that's got anything to do with it.
Hi jgoldb -- at first, using approach A, I was closing from whatever thread it "automatically" gets closed from, and getting this exception.
Now, using approach C, I am closing from the UI thread, in an event handler hooked up to my main window's Activated event. Still getting the exception using this technique.
Like the other respondants above, this happens maybe once out of every ten times I run the app, but I am able to repro it quite reliably by running in the debugger, and, when the splashscreen is displayed but before my main window has loaded and become visible, I click on Visual Studio to bring the focus away from the splashscreen and to Visual Studio.
This is on Vista SP1.
I can't send you the repro right now as the project is massive (and contains my clients' IP). Have you managed to repro this? Sounds like I am not the only one experiencing the issue. Please drop me mail if I can help somehow.
Silly question but is there a way for one to synchronize complete fade away of splash screen with main window launch?
Now, before the splash screen completely fades away my main window launches. I want the main window to launch only after the splash screen has completely faded away.
Your post is good - but it would be a whole lot better if all the left-hand side of the article showed.