2016-06-11 14 views
0

私は並列プログラミングの第一歩を踏み出します。私は最も単純なコードを書いたが、結果は混乱した。このコードは、プロデューサ - コンシューマパターンで上位10個の最近のアイテムを取得します。 1人の消費者と1人のプロデューサー。 2人の消費者がより良い仕事をしているが、間違っている。単純なプロデューサ - コンシューマの例C#辞書

public static void ProducerConsumer(string path) 
    { 
     var capacity = 50000; 
     var collection = new BlockingCollection<string>(capacity); 
     var dict = new Dictionary<string, int>(); 
     var tasks = new List<Task<Dictionary<string, int>>>(); 
     var producer = Task.Factory.StartNew(() => 
     { 

      Parallel.ForEach(File.ReadLines(path), (line) => 
      { 
       collection.Add(line); 
      }); 
      collection.CompleteAdding(); 
     }); 

     for (int i = 0; i < 1; i++) 
     { 
      var consumer = Task.Factory.StartNew<Dictionary<string, int>>(() => 
      { 
       var localDict = new Dictionary<string, int>(); 
       while (!collection.IsCompleted) 
       { 
        string line; 
        if (collection.TryTake(out line)) 
        { 
         Map(line, localDict); 
        } 
       } 
       return localDict; 
      }); 
      tasks.Add(consumer); 
     } 
     int count = 0; 
     while (tasks.Count > 0) 
     { 
      var id = Task.WaitAny(tasks.ToArray()); 

      var res = tasks[id].Result; 
      count += res.Sum(k => k.Value); 
      Aggregate(res, dict); 
      tasks.RemoveAt(id); 
     } 
     Console.WriteLine($"Values sum : {count}"); 
     ShowResult(dict); 
     ShowTotal(dict, "End"); 


    } 
    public static void Map(string line, Dictionary<string, int> dict) 
    { 
     var parts = line.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries); 
     var streetName = parts[3]; 
     if (dict.Keys.Contains(streetName)) 
     { 
      dict[streetName]++; 
     } 
     else 
     { 
      dict.Add(streetName, 1); 
     } 
    } 
    public static void ShowResult(Dictionary<string, int> dict) 
    { 

     var res = dict.OrderByDescending(r => r.Value).Take(10).ToList(); 

     foreach (var key in res) 
     { 
      Console.WriteLine($"{key.Key} - {key.Value}"); 
     } 
    } 
    public static void Aggregate(Dictionary<string, int> part, Dictionary<string, int> main) 
    { 

     foreach (var key in part.Keys) 
     { 
      if (main.Keys.Contains(key)) 
      { 
       main[key] += part[key]; 
      } 
      else 
      { 
       main.Add(key, 1); 
      } 
     } 
    } 

    public static void ShowTotal(Dictionary<string, int> dict, string mark = null) 
    { 
     Console.WriteLine($"{mark ?? ""} Keys: {dict.Keys.Count} - Values:{dict.Sum(s => s.Value)}"); 
    } 

デバッグ中は正しい手順が示されますが、結果には項目あたり1件のヒットと不正確な合計が表示されます。

+0

'main.Add;'私はあなたのアルゴリズムを理解していれば'main.Add(key、part [key])' –

+0

OMGでなければなりません。はい。愚かな間違い。ありがとうございました。 – Surgerer

答えて

0

ことshoud言った:(、キー1)

main.Add(key, part[key]) 
0

などがKooKizが、それは私があなたのアルゴリズムを理解していれば、それがあるべき

main.Add(key, part[key]) 
関連する問題