2014-10-02 64 views
-1

我正在处理+100000行并执行并行。这为更快的处理。并行不会执行所有记录

逻辑行为应该是:100000记录具有85000个groupId,意思是MyItems应该保存85000个记录。

这是不是这样的......我结束了不同的金额,然后85000

的过程如下:

从DB

获取所有值

获得所有的ID(不行ID的,而是一个的groupId)整数的数组内

过程中的groupId的

var myItems = new List<MyItem>(IDCounter.Length); 

Parallel.For(0, IDCounter.Length, (i, loopState) => 
{ 
    if(!SomeParameter) 
    loopState.Stop(); 

    var records = (from m in AllValues where m.GroupId == IDCounter[i] select m).ToList(); 

    var recordList = new List<MyRecords>(); 

    for(var j = 0; j<records.Count; j++) 
    { 
    recordList.Add(new MyRecord{Text = records[j].OtherValue}); 
    } 

    myItems.Add(new MyItem(Text = records[0].SomeValue, List = recordList)); 

}); 

有什么想法?

+2

“myItems”的类型是什么?如果它是'List ',那么你可以从多个threasd访问它,尽管它不是线程安全的。此外,这看起来像伪代码:'new MyItem(Text = records [0] .SomeValue,List = l)'。如果您发布*真实*代码,这将更容易帮助您 - 理想情况下是一个简短但完整的示例,展示问题。 – 2014-10-02 12:11:38

+0

由于您始终处理项目的完整列表,因此我无法看到这比顺序算法更有效。 – Stilgar 2014-10-02 12:11:52

+0

@JonSkeet;我以为我提供了一个简短但可用的真实代码,它与我所拥有的 – Schuere 2014-10-02 12:13:31

回答

2

为了确保您不会将项目同时添加到列表中,您可以使用concurrent collection

System.Collections.Concurrent命名空间提供了应在的地方对应的类型在System.CollectionsSystem.Collections.Generic命名空间,只要多个线程同时访问该集合使用几个线程安全的集合类。

一个例子是使用ConcurrentBag,因为您不能保证项目将添加到哪个订单。

表示一个线程安全的,无序的对象集合。

另一种方法是在添加到列表中以确保在任何给定时间只添加一个项目时使用锁定。

+0

在列表锁定争用成为问题的情况下,“添加到列表时使用锁定”的高级版本使用线程本地状态和“finally”。 'Parallel.For'为此提供了许多重载,其中每个线程都有自己的'List '来添加,并且它们全部放在“finally”委托内部以生成单个集合(MSDN示例:http ://msdn.microsoft.com/en-us/library/dd460703(v = vs.110)的.aspx)。 – 2014-10-02 12:15:43

+0

看起来不错,让我看看吧 – Schuere 2014-10-02 12:23:19

+0

@KirillShlenskiy不知道这个,会看看! – Sander 2014-10-02 12:39:51

3

您打电话myItems.Add多次同时。确保它是线程安全的。