首页 > 解决方案 > 是否通过带有异步的实体框架运行存储过程会忽略 context.timeout

问题描述

我尝试寻找有关通过 EF 异步运行存储过程的教程,但没有找到好的教程。

我有以下调用存储过程异步的函数

  1. 这段代码真的是异步的吗?
  2. 我的函数由于超时而失败,为什么 EF 在函数异步时关心超时?
  3. 我可以告诉 EF 在使用异步函数时忽略超时吗?

这是我的代码:

public async Task GenerateQueueAsync()    
{
    await Task.Run(() => ((MyEntities)_context).GenerateQueue());
}

标签: c#entity-frameworkstored-proceduresasync-await

解决方案


  1. 不,这不对。

  2. 这就是 EF 的设计方式!一个原因可能是为了防止无休止的死锁。但正如在第 3 条中回答的那样,您可以修改超时。

  3. 您可以在 Entity Framework 中将上下文 CommandTimeout 设置为 0 以告诉它无限期等待。为了在不同的 EF 版本中设置这个值:

Entity Framework Core 2.0: 引入了 IDesignTimeDbContextFactory:

public class SampleContextFactory : IDesignTimeDbContextFactory<SampleContext>
{
    public SampleContext CreateDbContext(string[] args)
    {
        var optionsBuilder = new DbContextOptionsBuilder<SampleContext>();
        optionsBuilder.UseSqlServer(
            @"Server=.\;Database=db;Trusted_Connection=True;", 
            opts => opts.CommandTimeout(0)
            );

        return new SampleContext(optionsBuilder.Options);
    }
}

并且您必须确保您的上下文具有一个将 DbContextOptions 对象作为参数的构造函数:

public SampleContext(DbContextOptions options) : base(options) { }

实体框架核心 1.0:

context.Database.SetCommandTimeout(0);

实体框架 6:

context.Database.CommandTimeout = 0;

注意修改查询执行超时的现有功能EF并不意味着在所有情况下都应该这样做。查询执行超时时间应设置得尽可能高,以保证大多数查询的成功执行,也应设置低至查询不会执行和浪费,甚至在某些情况下无休止地锁定资源。

在增加超时之前,您可以做几件事,例如:

查询优化:

主机软硬件增强

修改数据库表以获得正确的索引

最后根据这个答案使用async/awaitwith是性能优化EF的一个非常糟糕的主意。


推荐阅读