C# C:如何将任务转换为任务的IEnumerable
我有Nito.AsyncEx.AsyncCollection,我想把它包装成类似IAsyncEnumerable的东西 现在我只使用IEnumerable而不是IAsyncEnumerable 我需要像SelectMany这样的东西来平展列表。这就是问题所在。以下代码不起作用 有可能让它工作吗C# C:如何将任务转换为任务的IEnumerable,c#,.net,async-await,C#,.net,Async Await,我有Nito.AsyncEx.AsyncCollection,我想把它包装成类似IAsyncEnumerable的东西 现在我只使用IEnumerable而不是IAsyncEnumerable 我需要像SelectMany这样的东西来平展列表。这就是问题所在。以下代码不起作用 有可能让它工作吗 public static IEnumerable<Task<T>> Flatten<T>(IEnumerable<Task<T[]>> sou
public static IEnumerable<Task<T>> Flatten<T>(IEnumerable<Task<T[]>> source) {
foreach (Task<T[]> task in source) {
// We should convert Task<T[]> to IEnumerable of Task<T>
T[] result = await task;
foreach (T item in result) {
yield return Task.FromResult( item );
}
}
}
像这样使用
定义任务并在其中定义类型并等待结果,确保等待的是异步的。就像下面给出的方法一样
public async Task<IEnumerable<T>> getIEnumerable () {
return await yourresult.toListAsync();
}
最好的解决方案是等待几个月,直到iSyncEnumerable成为一个真正的东西。下一个最佳解决方案是使用IAsyncEnumerable from。但是现在 IEnumerable是一个同步拉式迭代器。因此,它必须同步提供它的T实例。更重要的是,它必须同步提供实例数 任务是单个项的异步拉取。它将仅异步提供其T实例 问题是:您想要的结果IEnumerable必须能够: 同步提供每个任务。不太难;如果绝对必要,可以使用TaskCompletionSource。 同步提供其计数。换句话说,它需要同步地提供每个任务。都是。考虑到您的输入,这是不可能的。 您的输入是IEnumerable。因为这是IEnumerable,所以可以同步获取计数,但这只是任务项的计数,即T[]项的计数。要执行展平操作,您必须等待每个任务项,以获得T项的计数。因此,您不能生成一个IEnumerable,它可以同步地知道它有多少项 您遇到了这种类型限制,因为IEnumerable与IAsyncEnumerable不同 你的选择是: 使用真正的IAsyncEnumerable,由您自己编写或通过System.Interactive.Async编写。优点:正确的类型允许语义精确的代码。缺点:IAsyncEnumerable的生产和消费目前仍是一个难题。 提前完成所有异步工作。优点:代码更简单。缺点:改变你想要的语义。 使用第二个选项,展平操作符可以如下所示:
public static async Task<IEnumerable<T>> Flatten<T>(IEnumerable<Task<T[]>> tasks)
{
var results = await Task.WhenAll(tasks);
return results.SelectMany(x => x);
}
在得到一个真正的IAsyncEnumerable之前,许多运算符将要求将来的任务以这样的方式结束。您能描述一下不工作吗?我在迭代器中使用wait方法。