我正在使用以下代码从数据库读取数据,我认为是逐行的:
public async IAsyncEnumerable<(int id, string body)> GetAllPostsAsync() {
using var postsQuery = _sqlConnection.CreateCommand();
postsQuery.CommandText = "SELECT Id, Body FROM Posts";
postsQuery.CommandType = CommandType.Text;
using var postsReader = await postsQuery.ExecuteReaderAsync(CommandBehavior.SequentialAccess);
while (await postsReader.ReadAsync()) {
var postId = await postsReader.GetFieldValueAsync<int>(0);
var postBody = await postsReader.GetFieldValueAsync<string>(1);
yield return (postId, postBody);
}
}
// In another class...
var postsToClean = _postsStore.GetAllPostsAsync();
_progressReporter.ConfigureTicks(postsCount);
await foreach (var post in postsToClean) {
await CleanupPostAsync(post);
}
据我了解,.net运行时将隐式调用CleanupPostAsync
,就像行从数据库发出一样快,但这与我看到的行为不一致:当我运行此代码并逐步执行时, yield return (postId, postBody)
没有命中其他行,最终引发SQL超时异常。
如果我一个接一个地接收行,而不是接收全部表数据,为什么会触发超时异常?
这个问题可能来自对异步流背后的理论的误解。
我正在使用C#8和VS 2019 Pro在.Net Core 3-preview5上运行此代码,查询Docker容器中的SQL Server Linux 14.0;