I have 7 different API calls that I want to make at the same time, and want the UI to be updated when each has been completed.
I have been fiddling with two different ways of doing this, chaining the requests, and shooting all requests off at the same time (in parallel).
Both seem to work but for some reason my Parallel tasks take significantly longer than when I chain them.
I am new to TPL / Parallelism so it may be my code that is incorrect, but wouldn't chaining the requests take longer since each would have to finish before the next started? Rather than in Parallel they all go out at once so you only have to wait for the slowest?
Please let me know if you see faults in my logic or code. I am happy with the response time I am getting but I do not understand why.
My "chaining" code:
await (Task.Run(() => WindLookup_DoWork()).
ContinueWith((t) => WindLookup_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()).
ContinueWith((t) => OFAC_DoWork()).ContinueWith((t) => OFAC_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()).
ContinueWith((t) => BCEGS_DoWork()).ContinueWith((t) => BCEGS_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()).
ContinueWith((t) => BOPTerritory_DoWork()).ContinueWith((t) => BOPTerritory_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()).
ContinueWith((t) => TerrorismTerritory_DoWork()).ContinueWith((t) => TerrorismTerritory_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()).
ContinueWith((t) => ProtectionClass_DoWork()).ContinueWith((t) => ProtectionClass_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()).
ContinueWith((t) => AddressValidation_DoWork()).ContinueWith((t) => AddressValidation_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()));
My "Parallel" code:
List<Task> taskList = new List<Task>();
taskList.Add(Task.Run(() => WindLookup_DoWork()).
ContinueWith((t) => WindLookup_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()));
taskList.Add(Task.Run(() => BCEGS_DoWork()).
ContinueWith((t) => BCEGS_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()));
taskList.Add(Task.Run(() => BOPTerritory_DoWork()).
ContinueWith((t) => BOPTerritory_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()));
taskList.Add(Task.Run(() => TerrorismTerritory_DoWork()).
ContinueWith((t) => TerrorismTerritory_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()));
taskList.Add(Task.Run(() => ProtectionClass_DoWork()).
ContinueWith((t) => ProtectionClass_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()));
taskList.Add(Task.Run(() => OFAC_DoWork()).
ContinueWith((t) => OFAC_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()));
taskList.Add(Task.Run(() => AddressValidation_DoWork()).
ContinueWith((t) => AddressValidation_ProcessResults(), TaskScheduler.FromCurrentSynchronizationContext()));
await Task.WhenAll(taskList.ToArray());
I've basically converted my old Background Worker code, which is why there are DoWork methods, and "callback" methods that update the UI.
The DoWork methods call a POST method to an API, and the process results simply populates a text area with the response xml.