I'm following this guide on BlockingCollection
to implement a Producer/Consumer pattern but still can't get my tasks to execute in parallel on the producer side.
The problem is my foreach
block is executing sequentially. From this question, I understand that I have to project the collection of PropertyLien<T>
as Task
s. How is that done?
// 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);