Зачем DataReader.ReadAsync тайм-аут в асинхронном потоке? - PullRequest
0 голосов
/ 27 мая 2019

Я использую следующий код для чтения данных из БД, в котором я считаю построчно:

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.

Почему это исключение тайм-аута срабатывает, если я получаю строки по одной, а не целый кусок данных таблицы?

Этот вопрос может возникнуть из-за неправильного пониманиятеория асинхронных потоков.

Я выполняю этот код на .Net Core 3-preview5 с C # 8 и VS 2019 Pro, запрашивая контейнер докера для SQL Server Linux 14.0;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...