gpt4 book ai didi

c# - Parallel.ForEach 缺少的项目

转载 作者:太空狗 更新时间:2023-10-30 00:40:44 25 4
gpt4 key购买 nike

我有以下代码:

HttpContext httpContext = HttpContext.Current;
RequestContext currentContext = RequestContextManager.CurrentContext;
ILifetimeScope currentSessionScope = PlatformContext.LifeTimeScope;

ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
ConcurrentBag<ParallelCalculateObj> forEachResult = new ConcurrentBag<ParallelCalculateObj>();
ConcurrentBag<ParallelCalculateObj> testForEachPassResult = new ConcurrentBag<ParallelCalculateObj>();

ParallelLoopResult loopResult = Parallel.ForEach(applications, () =>
{
HttpContext.Current = httpContext;
RequestContextManager.SetCustomCurrentContext(currentContext);
PlatformContext.LifeTimeScope = currentSessionScope;
return new ParallelCalculateObj();
}, (application, pls, localObj) =>
{
try
{
// some code
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
testForEachPassResult.Add(localObj);
return localObj;
}, forEachResult.Add);

其中 applications.Count = 3。执行上面的代码后,我得到了 forEachResult.Count = 2testForEachPassResult.Count = 3

为什么forEachResult 集合不包含所有的元素?也不异常(exception),ParallelLoopResult.IsCompleted = true

可能有助于解决我的问题的一件事是这三个项目在两个线程下运行:

  1. Item01 -> Thread.CurrentThread.ManagedThreadId 为 14
  2. Item02 -> Thread.CurrentThread.ManagedThreadId 为 10
  3. Item03 -> Thread.CurrentThread.ManagedThreadId 为 14

最佳答案

我认为您正在使用 Parallel.ForEach以错误的方式。

您正在使用具有本地状态的重载。此本地状态对于分区/线程是唯一的,但并非每次迭代都具有唯一的本地状态。

考虑将输入列表分成N 个分区。然后有 N 个本地状态。作为最后一步,您将那些 N 个局部状态组合成您的最终值。通常 N 将小于列表中的项目数,除非您使用更具体的重载之一,否则 TPL 将确定列表的分区方式。

由于您显然想用每次迭代的结果填充某个列表,因此您的本地状态也应该是一个列表,其中包含该特定分区的每次迭代的结果。对于最后的操作,您将所有列表合并为一个列表:

Parallel.ForEach(
applications,
() => new List<ParallelCalculateObj>(),
(application, pls, localObj) =>
{
// do something
var obj = new ParallelCalculateObj { /* data of the iteration */ };
localObj.Add(obj);
return localObj;
},
localObj =>
{
foreach (var result in localObj)
{
forEachResult.Add(result);
}
});

请注意,如果您这样做,则 forEachResult 中值的顺序将与 applications 中的项目顺序不一致。如果需要,则必须使用 ParallelLoopState 类的索引。

关于c# - Parallel.ForEach 缺少的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24907606/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com