So I'm working on a WPF Application that is performing some database operations on startup and recently decided to add a SplashScreen containing an "isIndeterminate" ProgressBar as a visual indicator that the application is performing background tasks.
However I can't get it to work without freezing the UI thread. First time working with async
/ await
so help is much appreciated. (using EF6 & locally installed MS SQL Server 2019 in case that's relevant)
Here's my code:
public partial class App : Application
{
private const int minSplashTime = 2000;
protected async override void OnStartup(StartupEventArgs e)
{
SplashScreenWindow splash = new SplashScreenWindow();
splash.Show();
base.OnStartup(e);
MainWindow mainWindow = new MainWindow();
Stopwatch timer = new Stopwatch();
timer.Start();
await AsyncDbTask();
timer.Stop();
// Wait remainingTime if minSplashTime is not reached yet
int remainingTime = minSplashTime - (int)timer.ElapsedMilliseconds;
if (remainingTime > 0)
{
await Task.Delay(remainingTime);
}
splash.Close();
mainWindow.Show();
}
private async Task AsyncDbTask()
{
using (DatabaseContext db = new DatabaseContext())
{
// PERFORMING DB OPERATIONS HERE
// [...]
await db.SaveChangesAsync();
}
}
}
Just because a method returns a Task<T>
does not mean it actually is run asynchronously. Some database engines does not support asynchronous queries and will run everything synchronous. And even if your database does support true async queries it does not necessarily mean that it cannot complete synchronously or that it will not do a significant amount of work on the caller thread.
A workaround would be to use Task.Run