IAsyncEnumerable с SqlDataReader и токен отмены зависает при отмене - PullRequest
0 голосов
/ 06 мая 2019

Я пытался протестировать новую функцию IAsyncEnumerable в c # 8 (а также предварительный просмотр .NET Core 3 WinForm), но все, кажется, связывается, когда я пытаюсь отменить задачу.Приостановка отладчика в цикле reader.ReadAsync while и продолжение заставляет все играть хорошо.Добавление Thread.Sleep(0) непосредственно перед while также иногда кажется полезным, но не всегда.

Я попытался перебрать .ConfigureAwait(false) вокруг, чтобы посмотреть, поможет ли это, но это не помогло.

Есть ли что-то не так с моим кодом или SqlClient.Асинхронное перечисление еще?

    private async IAsyncEnumerable<IDataRecord> SearchUIDataAsync(string searchTerm, CancellationToken cancellationToken)
    {
        using var con = new SqlConnection(_connectionString);
        using var cmd = new SqlCommand(Queries.UIDataSearch, con) {
            CommandTimeout = 0
        };

        cmd.Parameters.AddWithValue("@searchTerm", searchTerm);
        await con.OpenAsync(cancellationToken);

        using var reader = await cmd.ExecuteReaderAsync(cancellationToken);

        if (!reader.HasRows)
        {
            yield break;
        }

        while (await reader.ReadAsync(cancellationToken))
        {
            yield return reader;
        }
    }

Этот код называется формой события нажатия кнопки WinForm, как это

if (queryRunning)
{
    cts.Cancel();
    return;
}

try
{
    await foreach (var dr in SearchUIDataAsync(formDataSearchTerm.Text, cts.Token).WithCancellation(cts.Token))
    {
        //...
    }
}
catch (TaskCanceledException) { }

Для контекста cts - это поле CancellationTokenSource в форме

...