У меня есть метод, который выглядит так:
public static async IAsyncEnumerable<string> GetAllKnownAddressesAsync([EnumeratorCancellation] CancellationToken token = default)
{
await using var conn = new SqlConnection(ConnectionString);
await conn.OpenAsync(token).ConfigureAwait(false);
await using var getCommand = new SqlCommand("SELECT PublicAdr FROM dbo.Adr;", conn) {CommandTimeout = (int) TimeSpan.FromHours(10).TotalSeconds};
await using SqlDataReader r = await getCommand.ExecuteReaderAsync(token).ConfigureAwait(false);
int adrIndex = r.GetOrdinal("PublicAdr");
while (await r.ReadAsync(token).ConfigureAwait(false))
{
token.ThrowIfCancellationRequested();
yield return r.GetString(adrIndex);
}
}
вызывающий является основным в консольном приложении с этим кодом
try
{
await foreach (string val in DatabaseAccess.GetAllKnownAddressesAsync(token))
{
//Do Something later
}
}
catch (TaskCanceledException)
{
Console.WriteLine("Stopped");
}
Запрос Sql выполняется часами. Я ожидаю, что после запроса отмены с токеном l oop останавливается, и «Остановлено» должно отображаться почти сразу. Однако до появления сообщения «Остановлено» прошло очень много времени. Я хочу понять, почему это происходит, и есть ли способ немедленно выйти из ReadAsyn c l oop. Я также пробовал yield break без эффекта, когда заставлял отладчик прерывать выполнение, я вижу, что процесс ожидает ReadAsyn c.