c# - WPF - 数据库操作期间的 UI 锁定(EF6、异步/等待)
问题描述
所以我正在开发一个在启动时执行一些数据库操作的 WPF 应用程序,最近决定添加一个包含“isIndeterminate”ProgressBar 的 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();
}
}
}
解决方案
仅仅因为方法返回 aTask<T>
并不意味着它实际上是异步运行的。一些数据库引擎不支持异步查询,并将同步运行所有内容。即使您的数据库确实支持真正的异步查询,也不一定意味着它不能同步完成,或者它不会在调用者线程上做大量工作。
一种解决方法是使用Task.Run
推荐阅读
- node.js - PUT 方法回调,result.result 实际上是做什么的?
- javascript - 用进度条反应 Native Expo 飞溅
- ios - Flutter:无法从 ios 应用程序中删除自定义插件
- javascript - React-Redux:如何确保多个 fetch 请求在一个 action 被分派之前全部成功
- reactjs - reactjs中的OCR阅读器
- node.js - 如何修复此 NPM Watch ENOENT "\\run" 错误?
- windows-installer - 在 msi 中复制文件的自定义操作
- javascript - 按提交按钮时显示上传文件名列表
- sql - 尝试在 oracle sql 中运行脚本时忽略行
- spring - Spring webClient通过过滤器后生成NullPointException