IAsyncEnumerable 中缺少等待运算符时的警告消息

jsg*_*pil 7 c# async-await iasyncenumerable

当调用这样的方法而不执行await任务时,我们可以返回以下内容:

public Task<bool> GetBoolAsync()
{
    return Task.FromResult(true);
}
Run Code Online (Sandbox Code Playgroud)

a 相当于什么IAsyncEnumerable<>并避免警告。

async IAsyncEnumerable<bool> GetBoolsAsync() // <- Ugly warning
{
    yield return true;
    yield break;
}
Run Code Online (Sandbox Code Playgroud)

警告 CS1998 此异步方法缺少“await”运算符,并将同步运行。考虑使用“await”运算符等待非阻塞 API 调用,或使用“await Task.Run(...)”在后台线程上执行 CPU 密集型工作。

Jon*_*eet 9

我可能会编写一个同步迭代器方法,然后使用包ToAsyncEnumerable中的System.Linq.Async方法将其转换为异步版本。这是一个完整的示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        await foreach (bool x in GetBoolsAsync())
        {
            Console.WriteLine(x);
        }
    }

    // Method to return an IAsyncEnumerable<T>. It doesn't
    // need the async modifier.
    static IAsyncEnumerable<bool> GetBoolsAsync() =>
        GetBools().ToAsyncEnumerable();

    // Regular synchronous iterator method.
    static IEnumerable<bool> GetBools()
    {
        yield return true;
        yield break;
    }
}
Run Code Online (Sandbox Code Playgroud)

这符合(using)接口IAsyncEnumerable<T>,但允许同步实现,没有警告。请注意,async修饰符本身不是方法签名的一部分 - 它是实现细节。因此,在接口中指定为返回 a 的方法Task<T>IAsyncEnumerable<T>或者任何可以使用异步方法实现的方法,但不是必须如此。

当然,对于只想返回单个元素的简单示例,您可以ToAsyncEnumerable在数组或 的结果上使用Enumerable.Repeat。例如:

static IAsyncEnumerable<bool> GetBoolsAsync() =>
    new[] { true }.ToAsyncEnumerable();
Run Code Online (Sandbox Code Playgroud)