2017-11-15 15 views
-1

생산자/소비자 패턴을 구현하기 위해 this guideBlockingCollection에 올리 겠지만 여전히 생산자 측에서 병렬로 작업을 수행 할 수 없습니다.BlockingCollection을 사용하여 생산자/소비자 패턴 비동기에 항목 추가하기

문제는 내 foreach 블록이 순차적으로 실행되고 있습니다. this question에서 프로젝트 컬렉션이 PropertyLien<T>Task s 인 것으로 알고 있습니다. 어떻게 된거 야? @Evk에

// PropertyLien<T> is a class that models an asset (house/building/etc) 
var googleAddresses = new BlockingCollection<Tuple<PropertyLien<string>, IEnumerable<GoogleAddress>>>() 

// Consumer Threads 
var consumer = Task.Run(() => { 
    while(!googleAddresses.IsCompleted) { 
     var adr = googleAddresses.Take(); 
     // Do work 
    } 

    Console.WriteLine("No more addresses to process"); 
}); 

// Producer Threads 
var producer = Task.Factory.StartNew(async() => { 
    // TODO: PROBLEM here, this is executing synchronously 
    foreach(PropertyLien<string> property in properties) { 
     try { 
      // See: https://www.nuget.org/packages/Geocoding.net/ 
      await geocoder.GeocodeAsync(property.Address) 
       .ContinueWith(task => { 
        var googResults = task.Result; 
        googleAddresses.Add(property, googResults); 
       }); 
     } 
     catch {} 
    } 
    googleAddresses.CompleteAdding(); 
}); 

// Need to wait for both tasks to complete. 
Task.WaitAll(producer, consumer); 
+1

하지 마십시오'geocoder.GeocodeAsync'을 기다리고 있습니다. 대신 모든 작업을 목록 ('yourList.Add (geocoder.GeocodeAsync (....)) '에 넣은 다음''Task.WhenAll (yourList)'를 기다리십시오. – Evk

답변

0

덕분에,이 답이다 :

// Producer Threads 
var producer = Task.Factory.StartNew(async() => { 
    var tasks = properties.Select(property => { 
     return geocoder.GeocodeAsync(property.Address) 
      .ContinueWith(task => { 
       // Do work 
      }); 
    }); 

    await Task.WhenAll(tasks); 
    googleAddresses.CompleteAdding(); 
});