带有SqlDataReader的IAsyncEnumerable和取消令牌在取消时挂起

时间:2019-05-06 16:45:05

标签: c# .net-core ado.net .net-core-3.0 iasyncenumerable

我试图测试c#8中的新IAsyncEnumerable功能(以及.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字段

0 个答案:

没有答案