首页 > 解决方案 > 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();
        }
    }
}

标签: c#wpfuser-interfaceasync-awaitentity-framework-6

解决方案


仅仅因为方法返回 aTask<T>并不意味着它实际上是异步运行的。一些数据库引擎不支持异步查询,并将同步运行所有内容。即使您的数据库确实支持真正的异步查询,也不一定意味着它不能同步完成,或者它不会在调用者线程上做大量工作。

一种解决方法是使用Task.Run


推荐阅读