首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Parallel.ForEach丢失数据

Parallel.ForEach丢失数据
EN

Stack Overflow用户
提问于 2016-03-18 13:18:02
回答 4查看 3.2K关注 0票数 11

Parallel.ForEach有助于提高性能,但是,我看到数据丢失了。

尝试变量结果,processedData为ConcurrentBag<IwrRows>

1)

代码语言:javascript
复制
Parallel.ForEach(results, () => new ConcurrentBag<IwrRows>(), (n, loopState, localData)    =>
{
 return ProcessData(n); // ProcessData complicated business logic
}, (localData) => AddRows(localData, processedData, obj)
);

2)

代码语言:javascript
复制
await Task.Run(() => Parallel.ForEach(results, item =>
        {
            ProcessData(item, processedData);  
        }));

3)

代码语言:javascript
复制
Parallel.ForEach(results, item =>
 {
 ProcessData(item, processedData);
 });

他们都输掉了几排。

当我使用foreach块时,它会始终如一地返回相同的值,但是它的速度要慢4倍。

代码语言:javascript
复制
foreach (var item in results)
        {
            // ProcessData returns a List<IwrRows>
            processedData.AddRange(ProcessData(item));
        }

不知道我在这里错过了什么。

结果- 51112 Foreach返回41316行返回。ForeachParallel返回的41308或41313或41314随每次运行而不同。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-03-18 13:33:51

你似乎在为结果而挣扎,并把它们重新列入一个连贯的列表中。您可以使用PLinQ,这样就不必费心使用线程安全的结果容器了:

代码语言:javascript
复制
var processedData = yourData.AsParallel().Select(ProcessData).ToList();
票数 6
EN

Stack Overflow用户

发布于 2016-03-18 13:26:16

您的问题似乎出现在: AddRows(localData,processedData,obj)中。此方法可能是将数据添加到一个不是线程安全的列表中。您应该添加到线程安全列表中,或者在添加数据时进行一些同步。

票数 4
EN

Stack Overflow用户

发布于 2016-03-18 13:36:06

我认为在2)中使用await Task.Run是无用的。

如果Foreach returns 41316 rows back for Results - 51112的问题不在Parallel.ForEach中,而是在您的添加/处理机制中。请记住,即使ConcurrentBag保证其上的每个操作都是线程安全的,它也不会处理重复的操作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36085452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档