实体框架保存更改异步阻止我的 UI

本文关键字:我的 UI 异步 框架 保存更改 实体 | 更新日期: 2023-09-27 18:21:06

private async void button4_Click(object sender, EventArgs e)
        {
            try
            {
                MyDbContext context = new MyDbContext();
                for (int i = 0; i < 10000; i++)
                {
                    context.Table1.Add(new Table1() { Name = "jon" + i});
                }
                await context.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

在此代码中,上下文。保存更改异步阻止我的 UI,直到将所有记录保存在数据库中。为什么会这样?我该如何解决?

更新:

private async void button9_Click(object sender, EventArgs e)
    {
        try
        {
            MyDbContext context = new MyDbContext();
            for (int i = 0; i < 10000; i++)
            {
                context.Table1.Add(new Table1() { Name = "jon" + i });
            }
            MessageBox.Show("Start");
            await Task.Delay(20000);
            MessageBox.Show("End");
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

为什么在上面的代码中 UI 直到延迟结束才阻止?但是在前面的代码中UI被阻止了吗?

实体框架保存更改异步阻止我的 UI

await行上方的代码导致了问题。

试试这个:

private async void button4_Click(object sender, EventArgs e)
        {
            try
            {
                await Task.Run(() =>
                {
                    MyDbContext context = new MyDbContext();
                    for (int i = 0; i < 10000; i++)
                    {
                        context.Table1.Add(new Table1() { Name = "jon" + i });
                    }
                    await context.SaveChangesAsync();
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

这将使所有代码异步运行,并且不应再阻止 UI。您可以尝试调试for loopMyDbContext行,看看为什么它们花费的时间比应有的时间多。

这在文档中提到:

SQLite 不支持异步 I/O.异步 ADO.NET 方法将在 Microsoft.Data.Sqlite 中同步执行。避免打电话给他们。

这包括 EF 核心。您可以使用 Task.Run 解决此问题:

await Task.Run(() =>
{
    MyDbContext context = new MyDbContext();
    for (int i = 0; i < 10000; i++)
    {
        context.Table1.Add(new Table1() { Name = "jon" + i });
    }
    context.SaveChanges();
});
var items = await Task.Run(() =>
{
    MyDbContext context = new MyDbContext();
    context.ToList();
});