2

我发现该DatabaseFacade.SetCommandTimeout方法和该SqlServerDbContextOptionsBuilder.CommandTimeout方法都没有对我的代码产生任何影响,而是一个长时间运行的 SQL 命令只是无限期地继续。

我的上下文对象看起来像这样:

public class MyDataContext : DbContext
{
    public MyDataContext()
    {
        base.Database.SetCommandTimeout(60);
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
    {
        ...
        optionsBuilder.UseSqlServer(connection, sqlServerOptions => sqlServerOptions.CommandTimeout(60));
    }
}

但是当我在我的 Web API 中执行代码时:


using var dbContext = new MyDataContext();
var timeout = dbContext.Database.GetCommandTimeout(); // this, as expected, returns "60"
var listOfEntities = dbContext.MyLargeSetOfEntities.ToList(); // this, however, just runs way longer than a minute (it is returning an immense amount of data to test the timeout)

有没有什么地方可以覆盖这个值并使其无限期?

4

1 回答 1

4

该值没有被覆盖,但是您对它的作用有错误的期望。

它正在返回大量数据来测试超时

命令超时仅适用于数据库命令的ExecuteXYZ部分,对于查询而言,即限制执行 SQL 查询的时间(想象一些具有许多连接、笛卡尔积、分组依据、子查询等的超级复杂 SQL 命令,这可能永远运行。或者某些访问的表被另一个长时间运行的事务锁定等)。ExecuteReader

一旦执行 SQL 命令,使用结果(在这种情况下读取返回的数据)不受任何限制 - 没有这样的设置,也不可能。

如果要限制整个操作的时间,请考虑将命令超时设置与异步取消支持结合起来,例如在异步方法中

var listOfEntities = await dbContext.MyLargeSetOfEntities
    .ToListAsync(new CancellationTokenSource(TimeSpan.FromSeconds(60)).Token);
于 2021-04-23T06:41:22.567 回答