0

我有一个返回IAsyncEnumerable. 我想await完成它,但我不在乎任何结果。我只关心调用函数的副作用。

如何在不使用 for 循环或将其转换为容器(例如)的情况下轻松await完成IAsyncEnumerablefor ToListAsync

4

2 回答 2

2

您可以使用System.Linq.AsyncLastOrDefaultAsync包中的运算符,然后使用扩展方法将结果转换为 a 。为了更加方便,您可以将这两个操作组合到一个扩展方法中:ValueTask<T>TaskAsTaskToTask

/// <summary>
/// Retrieves a Task object that represents the completion of this IAsyncEnumerable.
/// </summary>
public static Task ToTask<T>(this IAsyncEnumerable<T> source)
{
    return source.LastOrDefaultAsync().AsTask();
}

但老实说,手动执行循环更简单,可能更有效:

public async static Task ToTask<T>(this IAsyncEnumerable<T> source)
{
    await foreach (var _ in source.ConfigureAwait(false)) { }
}

运算符将LastOrDefaultAsync在可枚举的生命周期内将最后一个发出的元素保存在内存中,这可能会阻止该元素被及时地进行垃圾收集。您可以通过在查询中包含System.Interactive.AsyncIgnoreElements包中的运算符来防止这种情况发生,但我认为这太麻烦了。

于 2021-04-13T11:08:02.200 回答
0

简短的回答:你不能。


记录器答案:询问

如何在不使用 for 循环或将其转换为容器(例如 ToListAsync)的情况下轻松等待 IAsyncEnumerable 完成?

就像问

如何在不使用 or 之类的东西的情况下等待任务的await完成?.Result.Wait()

知道什么时候IAsyncEnumerable完成的方法是调用await MoveNextAsync()它的迭代器并返回false。最简洁的方法是

await foreach (var _ in AsyncGenerator()) ; // The semicolon is necessary
于 2021-04-13T10:02:51.537 回答