我尝试寻找有关通过EF异步运行存储过程的教程,但没有找到好的教程。
我有以下调用存储过程异步的函数
- 这段代码真的是异步的吗?
- 我的函数因超时而失败,为什么 EF 在函数异步时关心超时?
- 是否可以告诉 EF 在使用异步函数时忽略超时?
这是我的代码:
public async Task GenerateQueueAsync()
{
await Task.Run(() => ((MyEntities)_context).GenerateQueue());
}
-
不,不是。
-
这就是 EF 的设计方式!一个原因可能是防止无休止的僵局。但如第 3 条所述,您可以修改超时。
-
可以在实体框架中将上下文 CommandTimeout 设置为 0,以告知它无限期等待。为了在不同的EF版本中设置此值:
实体框架核心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
提供的修改查询执行超时的现有功能并不意味着在所有情况下都应执行此操作。查询执行超时应设置为尽可能高,以保证大多数查询的成功执行,也应设置为查询不会执行和浪费,甚至在某些情况下无休止地锁定资源。
在增加超时之前,您可以执行以下几项操作,例如:
查询优化:
通过使用联接避免
TSQL
或EF
中的循环。在 TSQL 中使用适当的方法(如 SQL 大容量插入(或高效的 EF 库(如 EF 大容量插入(实现正确的批量操作
了解 EF 中的延迟、急切和显式加载并正确使用它们
主机软件和硬件增强
修改数据库表以具有正确的索引
最后,根据这个答案,将async/await
与EF
一起使用对于性能优化来说是一个非常糟糕的主意。