要设置上下文,应用程序正在服务器上运行,其中+ -20个其他应用程序正在进行多线程处理,但此过程仅适用于服务器上的2个应用程序。我从来没有在其他应用程序上出现过这种错误,它们都使用ForEachAsync方法。在这个特定的应用程序,我不得不添加一些多线程,我有时会在使用ForEachAsync时出现此错误:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: partitionCount
at System.Collections.Concurrent.Partitioner.DynamicPartitionerForIEnumerable`1.GetOrderablePartitions(Int32 partitionCount)
at System.Collections.Concurrent.OrderablePartitioner`1.GetPartitions(Int32 partitionCount)
at Common.AsyncHelper.ForEachAsync[T](IEnumerable`1 source, Func`2 taskSelector, Int32 maxParallelism) in ...\AsyncHelper.cs:line 15
以下是方法:
public static Task ForEachAsync<T>(this IEnumerable<T> source, Func<T, Task> taskSelector, int maxParallelism)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(maxParallelism)
select Task.Run(async delegate {
using (partition)
while (partition.MoveNext())
await taskSelector(partition.Current);
}));
}
以下是我如何使用它:
int parallel = list.Count() < 8 ? list.Count() : 8;
await list.ForEachAsync(async a => await Process(param1, param2),parallel);
我是否使用了很多并行性?编辑:看起来空列表就是问题。
这是一个最小的工作示例:
这是我的AsyncHelper
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Common
{
public static class AsyncHelper
{
public static Task ForEachAsync<T>(this IEnumerable<T> source, Func<T, Task> taskSelector, int maxParallelism)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(maxParallelism)
select Task.Run(async delegate {
using (partition)
while (partition.MoveNext())
await taskSelector(partition.Current);
}));
}
}
}
我想要做的是处理一个列表并将结果设置在另一个列表中,其中包含max // = 8:
var temp = new ConcurrentBag<TempResponse>();
int parallel = 1;
if(someList.Any(c => c.Valid))
parallel = someList.Count(c => c.Valid) < 8 ? someList.Count(c => c.Valid) : 8;
await someList.ForEachAsync(async a => temp.Add(await Process(a.Condition, a.State, a.Name)),parallel);
答案 0 :(得分:2)
此错误仅表示您将0
作为maxParallelism
传递给您的函数。
int parallel = list.Count() < 8 ? list.Count() : 8;
如果目标list
为空,则为零;如果Partitioner.Create(...).GetPartitions()
调用为零则为零。
因此,只需检查列表是否为空,如果是 - 不执行任何操作(没有理由在其上调用ForEachAsync
)。