Como posso fazer `aguardar…` trabalhar com `yield return` (ou seja, dentro de um método iterador)?

Eu tenho um código existente semelhante a:

IEnumerable<SomeClass> GetStuff()
{
    using (SqlConnection conn = new SqlConnection(connectionString))
    using (SqlCommand cmd = new SqlCommand(sql, conn)
    {
        conn.Open();
        SqlDataReader reader = cmd.ExecuteReader();
        while (reader.Read())
        {
            SomeClass someClass = f(reader); // create instance based on returned row
            yield return someClass;
        }
    } 
}

Parece que eu poderia me beneficiar usandoreader.ReadAsync(). No entanto, se eu apenas modificar a linha:

        while (await reader.ReadAsync())

o compilador me informa queawait só pode ser usado em métodos marcados comasynce sugere que eu modifique a assinatura do método para ser:

async Task<IEnumerable<SomeClass>> GetStuff()

No entanto, isso fazGetStuff() inutilizável porque:

O corpo deGetStuff() não pode ser um bloco iterador porqueTask<IEnumerable<SomeClass>> não é um tipo de interface do iterador.

Tenho certeza que estou perdendo um conceito chave com o modelo de programação assíncrona.

Questões:

Eu posso usarReadAsync() no meu iterador? Como?Como posso pensar sobre o paradigma assíncrono de forma diferente para entender como ele funciona nesse tipo de situação?

questionAnswers(3)

yourAnswerToTheQuestion