2017-11-15 7 views
-1

this guideBlockingCollectionに送信してプロデューサ/コンシューマパターンを実装しても、プロデューサ側で並列に実行するタスクを取得できません。BlockingCollectionを使用してプロデューサ/コンシューマパターンasyncにアイテムを追加する

問題は私のforeachブロックが順番に実行されていることです。 this questionから、私はプロジェクトのコレクションPropertyLien<T>Taskのコレクションを持っていることを理解しています。それはどうですか? @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(....))')、 'await 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(); 
}); 
関連する問題