2016-10-20 4 views
0

を比較しない、私は別のリストと比較するネストされたリストを引き出すためにスレッドを使用しようとしている、このスレッディングとリスト、どのように私はそれぞれ通過し、

List<KeyPairValues<string, List<string>> mainList = new List<KeyPairValues<string, List<string>>(); 

// In my actual code I create these list through a loop 
List<string> A = new List<string>(); 
A.Add("Car"); 
A.Add("Plain"); 
A.Add("Boat"); 

List<string> B = new List<string>(); 
B.Add("Flower"); 
B.Add("Dog"); 
B.Add("House"); 

List<string> C = new List<string>(); 
C.Add("Appartment"); 
C.Add("Plant"); 
C.Add("Candy"); 

mainList.Add(new KeyValuePair<string, List<string>>("unRead", A)); 
mainList.Add(new KeyValuePair<string, List<string>>("unRead", B)); 
mainList.Add(new KeyValuePair<string, List<string>>("unRead", C)); 

List<string> compareList = new List<string>(); 
compareList.Add("Car"); 
compareList.Add("Boat"); 
compareList.Add("Dog"); 
List<string> resList = new List<string>(); 

ような何か私の最初の考えはしました私の現在のコードでは、mainListに32個のリストがあります。

foreach(var item in mainList) 
{ 
    if(item.key == "unRead") 
    { 
     foreach(var subItem in item.value) // evt do a List<string> temp = item.value first 
     { 
      foreach(var compItem in compareList) 
      { 
       if(compItem == subItem) resList.Add(compItem); 
      } 
     } 
     item.remove(); // I actualy wanted to change from unRead to read, but I figured I could just remove it from the list. 
    } 
} 

私はスレッドを使用してseperatスレッド、10か何かの最大スレッド量とEVTに各リストを通過する場合、これはfasteことができるはずです。 私はこれをやっていました。

foreach(var item in mainList) 
{ 
    Thread myThread = new Thread(() => 
    { 
     if(item.key == "unRead") 
     { 
      foreach(var subItem in item.value) // evt do a List<string> temp = item.value first 
      { 
       foreach(var compItem in compareList) 
       { 
        if(compItem == subItem) resList.Add(compItem); 
       } 
      } 
      item.remove(); // I actualy wanted to change from unRead to read, but I figured I could just remove it from the list. 
     } 
    }); 
    myThread.start(); 
} 

しかし、これはだから私は間違って何をやっている...まったく

を任意の期待出力を与えるdident?

+0

あなたは、正確に予想される結果がどのように見えるのか、そして現在の結果は何ですか? – nozzleman

+0

それとも、物事をスピードアップすることですか? – nozzleman

+0

'resList'は複数のスレッドで修正されているため、ロックする必要があります。 –

答えて

2

resListは、複数のスレッドで変更されるため、ロックする必要があります。また、すべてのスレッドが完了するまで待つ必要があります。これにはParallel.Foreach()を使用してください。例えば

Parallel.Foreach(mainList, (item) => 
{ 
    if(item.key == "unRead") 
    { 
     foreach(var subItem in item.value) // evt do a List<string> temp = item.value first 
     { 
      foreach(var compItem in compareList) 
      { 
       if(compItem == subItem) 
        lock(resList) 
         resList.Add(compItem); 
      } 
     } 
    } 
}); 

mainList.RemoveAll(item => item.key == "unRead"); 

これは、いくつかのLINQ-魔法で短絡させることができる。

var resList = mainList.Where(item => item.key == "unRead") 
         .SelectMany(subitem => compareList.Contains(subitem))).ToList(); 

糸通し/ロックせず

Jeroneバンランゲンが指摘したように、すでに、問題はリストへのアクセスが競合状態を引き起こしているということですcompareList

+0

このロジックでは共通のリストを見つけることができます。List duplicates = list1.Intersect(list2).ToList(); –

0

のための代わりList<>HashSet<>を使用するのに便利だろう。ロックを導入することでこれを解決することも、スレッドセーフなコレクション実装を使用することもできます。後者のアプローチには、ロックフリーで動作するクラスが含まれているため、より良いパフォーマンス結果を得ることができます。たとえば、System.Collections.Concurrent.ConcurrentBagをご覧ください。

いずれにせよ、最初に最適化するには、これらのリストに10以上の要素が含まれていると思われる場合は、ハッシュセットを使用することが間違いないでしょう。

関連する問題