I am trying to optimize the loading times for my WPF prism application. The loading is basically a loop of using reflection to create instances of UI elements and then adding them to the main window (the shell) in a tab control.
Since we are limited to using a single thread to create all the objects, what would be the optimal way to speed up loading / create a better user experience?
These are the options I have so far:
Use lazy loading. Only load the tab when the user first clicks on it. But that would have a 4-5 second delay opening the first time as it gets initialized on demand.
Cache all the reflection calls. I actually did that, but it did not speed anything up at all. Most of the time occurs during the rendering of the controls...
?
Any suggestions would be greatly appreciated for this tricky problem.
You're pretty much stuck as you can only load objects on the main thread, so I don't think you'll make it load any faster.
What you can do is distract the user: I have an animated splash screen that take about 10 seconds to work its way through the animation sequence. This serves a number of purposes:
To ensure smooth animation you need to create a second dispatcher. Here's how I do it:
public class AppEntry : Application
{
private static ManualResetEvent _resetSplashCreated;
internal static Thread SplashThread { get; set; }
internal static SplashWindow SplashWindow { get; set; }
private static void ShowSplash()
{
SplashWindow = new SplashWindow();
SplashWindow.Show();
_resetSplashCreated.Set();
Dispatcher.Run();
}
[STAThread]
public static void Main()
{
_resetSplashCreated = new ManualResetEvent(false);
SplashThread = new Thread(ShowSplash);
SplashThread.SetApartmentState(ApartmentState.STA);
SplashThread.IsBackground = true;
SplashThread.Name = "Splash Screen";
SplashThread.Start();
_resetSplashCreated.WaitOne();
var app = new App();
app.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(app_DispatcherUnhandledException);
app.InitializeComponent();
app.Run();
}
static void app_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
// MessageBox.Show(e.Exception.StackTrace);
}
}
I set the AppEntry class as my Startup Object in the Project Properties/Application tab.
I close my splash screen at the end of my OnStartup method in App:
AppEntry.SplashWindow.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() => AppEntry.SplashWindow.Close()));
Is this faster? No Does the user think it's faster? Yes
Sometimes, if you can't give them speed, you can give them activity. It's a nice placebo.
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