【发布时间】:2022-03-17 20:46:23
【问题描述】:
我正在尝试将 Stephen Toub's ForEachAsync<T> 扩展方法更改为返回结果的扩展...
斯蒂芬的扩展:
public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select Task.Run(async delegate {
using (partition)
while (partition.MoveNext())
await body(partition.Current);
}));
}
我的方法(不起作用;任务被执行但结果错误)
public static Task<TResult[]> ForEachAsync<T, TResult>(this IList<T> source,
int degreeOfParallelism, Func<T, Task<TResult>> body)
{
return Task.WhenAll<TResult>(
from partition in Partitioner.Create(source).GetPartitions(degreeOfParallelism)
select Task.Run<TResult>(async () =
{
using (partition)
while (partition.MoveNext())
await body(partition.Current); // When I "return await",
// I get good results but only one per partition
return default(TResult);
}));
}
我知道我必须以某种方式返回 (WhenAll?) 最后一部分的结果,但我还不知道该怎么做...
更新:即使所有任务都已执行,我得到的结果也只是 degreeOfParallelism 次 null(我猜是因为 default(TResult))。我也试过return await body(...),然后结果很好,但只有degreeOfParallelism的任务数被执行了。
【问题讨论】:
-
"Result is wrong" 根本无法描述您所看到的内容。您返回
default(TResult)的事实似乎不是一个好的开始。如果您提供一个简短但完整的程序来演示问题,这将有所帮助,包括示例输入、预期输出和实际输出。 (我强烈怀疑你在这里想要SelectMany而不是Select,基本上......) -
@JonSkeet:添加了更新
-
您不能列一个列表,将您的结果添加到该列表中,然后在完成所有操作后在最后返回吗?
-
@poke: 也想过,但我相信这不是真正的异步?!?
-
您当前发布的代码无法编译,这无济于事...
标签: c# asynchronous concurrency task-parallel-library parallel.foreachasync