如何使 `await ...` 与 `yield return` 一起工作(即在迭代器方法中)?

How can I make `await …` work with `yield return` (i.e. inside an iterator method)?(如何使 `await ...` 与 `yield return` 一起工作(即在迭代器方法中)?)

本文介绍了如何使 `await ...` 与 `yield return` 一起工作(即在迭代器方法中)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的现有代码类似于:

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;
        }
    } 
}

看来我可以通过使用 reader.ReadAsync() 受益.但是,如果我只修改一行:

It seems I could benefit by using reader.ReadAsync(). However, if I just modify the one line:

        while (await reader.ReadAsync())

编译器告诉我 await 只能用在标有 async 的方法中,并建议我将方法签名修改为:

the compiler informs me that await can only be used in methods marked with async, and suggests I modify the method signature to be:

async Task<IEnumerable<SomeClass>> GetStuff()

但是,这样做会使 GetStuff() 无法使用,因为:

However, doing that makes GetStuff() unusable because:

GetStuff() 的主体不能是迭代器块,因为 Task> 不是迭代器接口类型.

The body of GetStuff() cannot be an iterator block because Task<IEnumerable<SomeClass>> is not an iterator interface type.

我确定我错过了异步编程模型的一个关键概念.

I'm sure I am missing a key concept with the async programming model.

问题:

  • 我可以在我的迭代器中使用 ReadAsync() 吗?怎么样?
  • 如何以不同的方式思考异步范式,以便了解它在这种情况下的工作原理?

推荐答案

从 C# 8 开始,这可以通过 IAsyncEnumerable

As of C# 8, this can be accomplished with IAsyncEnumerable

修改代码:

async IAsyncEnumerable<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;
        }
    } 
}

像这样消费它:

await foreach (var stuff in GetStuff())
    ...

这篇关于如何使 `await ...` 与 `yield return` 一起工作(即在迭代器方法中)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何使 `await ...` 与 `yield return` 一起工作(即在迭代器方法中)?

基础教程推荐