如何在丢弃结果时等待 IAsyncEnumerable

问题描述

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

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

解决方法

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

/// <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 运算符将在可枚举的生命周期内将最后发出的元素保存在内存中,这可能会阻止元素及时被垃圾回收。您可以通过在查询中包含 IgnoreElements 包中的 System.Interactive.Async 运算符来防止这种情况发生,但我认为这太麻烦了。

,

简短回答:你不能。


Loger 回答:询问

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

就像在问

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

知道 IAsyncEnumerable 何时完成的方法是在其迭代器上调用 await MoveNextAsync() 并返回 false。最简洁的方法是

await foreach (var _ in AsyncGenerator()) ; // The semicolon is necessary

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...