2016-06-11 3 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)}"); 
    } 

디버깅 중에는 올바른 단계가 표시되지만 결과에는 항목 당 하나의 적중 횟수와 잘못된 총 수가 표시됩니다.

+0

'main.Add (키, 1);'나는 당신의 알고리즘을 이해한다면 , 그것은'main.Add (key, part [key]) '이어야합니다. –

+0

OMG. 예. 멍청한 실수. 고맙습니다. – Surgerer

답변

0

될 갈까요, KooKiz 말했다 :

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

처럼 내가 당신의 알고리즘을 이해한다면, 그것이 있어야이

main.Add(key, part[key])