WPF - UI 在数据库操作期间锁定(EF6,async/await)
WPF - UI locking up during Database operations (EF6, async/await)
所以我正在开发一个 WPF 应用程序,该应用程序在启动时执行一些数据库操作,最近决定添加一个包含“isIndeterminate”进度条的 SplashScreen 作为应用程序正在执行后台任务的可视指示器。
但是,如果不冻结 UI 线程,我就无法让它工作。第一次使用 async
/ await
非常感谢帮助。 (如果相关,则使用 EF6 和本地安装的 MS SQL Server 2019)
这是我的代码:
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();
}
}
}
只是因为一个方法 returns 一个 Task<T>
并不意味着它实际上是 运行 异步的。一些数据库引擎不支持异步查询,并且 运行 一切都是同步的。即使您的数据库确实支持真正的异步查询,也并不一定意味着它无法同步完成或不会在调用者线程上执行大量工作。
解决方法是使用 Task.Run
所以我正在开发一个 WPF 应用程序,该应用程序在启动时执行一些数据库操作,最近决定添加一个包含“isIndeterminate”进度条的 SplashScreen 作为应用程序正在执行后台任务的可视指示器。
但是,如果不冻结 UI 线程,我就无法让它工作。第一次使用 async
/ await
非常感谢帮助。 (如果相关,则使用 EF6 和本地安装的 MS SQL Server 2019)
这是我的代码:
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();
}
}
}
只是因为一个方法 returns 一个 Task<T>
并不意味着它实际上是 运行 异步的。一些数据库引擎不支持异步查询,并且 运行 一切都是同步的。即使您的数据库确实支持真正的异步查询,也并不一定意味着它无法同步完成或不会在调用者线程上执行大量工作。
解决方法是使用 Task.Run