WPF UI在等待的DbContext阻挡 [英] WPF UI blocking while awaiting DbContext

查看:416
本文介绍了WPF UI在等待的DbContext阻挡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与异步尝试等待,我遇到了不应该发生的UI阻塞。

I'm experimenting with async await and I'm encountering UI blocking that shouldn't be happening.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        LoadButton.Click += LoadButton_OnClick;
    }

    private async void LoadButton_OnClick(object sender, RoutedEventArgs e)
    {
        LoadButton.IsEnabled = false;

        // await Task.Delay(2000);

        using(TestContext ctx = new TestContext())
        {
            IList<User> users = await ctx.Users.ToListAsync();
        }

        LoadButton.IsEnabled = true;
    }
}

如果我评论的的DbContext位并取消Task.Delay,它的行为如预期 - 非阻塞UI

If I comment the DbContext bit and uncomment Task.Delay, it behaves as expected - non blocking the UI.

根据我的理解,ToListAsync()方法,仍是从UI线程调用的,但不应该阻止它。即使方法是CPU限制的(可能不是)会引起滞后,没有一个完整的块。

Based on my understanding, the ToListAsync() method is still invoked from the UI thread but shouldn't block it. Even if the method is CPU-bound (probably isn't) it would cause lag, not a complete block.

我的问题:

我是否正确地理解这一点?

Do I understand this correctly?

为什么我的UI阻塞而ToListAsync()?

Why is my UI blocking while awaiting on ToListAsync() ?

修改

我试图调用此方法暖一切,确保它不会在建立第一个连接块之前做一个数据库调用。我也尝试添加几千个条目到DbSet和等候SaveChangesAsync,同样的事情发生了 - 用户界面完全冻结几秒钟

I tried doing a database call before calling this method to warm everything and ensure it doesn't block on establishing the first connection. Also I tried adding a couple of thousand entries to the DbSet and awaiting on SaveChangesAsync and the same thing happens - the UI freezes completely for several seconds.

编辑2

我试着用同样的code另一个例子,它似乎是工作。所不同的是,在第一个例子中,我使用code首先和SQL CE并在工作示例数据库优先和SQL Server。

I tried another example with the same code and it seems to be working. The difference is that in first example I'm using Code First and SQL CE and in the working example Database First and SQL Server.

推荐答案

在SQL Server CE使用的连接对象不是<一个href=\"https://social.msdn.microsoft.com/Forums/sqlserver/en-US/df341f51-b3f6-4cd4-a7ed-d2149c0c4ce2/multithreaded-programming-with-sql-server-compact?forum=sqlce\"相对=nofollow>线程(自然异步API是未实现)。我相信您遇到,因为它是等待时,它创建的DbContext ,而不是控制权返回到UI线程的线程上执行这个问题上与SQL CE。尝试实例化的DbContext 中的工作,等待结果。

The connection objects used in SQL Server CE are not threadsafe (the naturally async APIs are not implemented). I believe you are encountering this issue with SQL CE as it is executing on the thread which created the DbContext and not returning control back to the UI thread when awaited. Try instantiating the DbContext within a Task and awaiting the result.

LoadButton.IsEnabled = false;

var users = await Task.Run(() => 
{
    using(TestContext ctx = new TestContext())
    {
        return ctx.Users.ToList();
    }
});

LoadButton.IsEnabled = true;

这篇关于WPF UI在等待的DbContext阻挡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆