Benji
Benji

Reputation: 509

Task.WhenAny throttling efficiency

I was recently reading through some documentation for using TAP, specifically this page under the smaller heading "Task.WhenAny." They state 4 primary purposes for the Task.WhenAny:

Underneath the interleaving (and indirectly the throttling) subsection they have this code

List<Task<Bitmap>> imageTasks = 
(from imageUrl in urls select GetBitmapAsync(imageUrl)).ToList();
while(imageTasks.Count > 0)
{
    try
    {
        Task<Bitmap> imageTask = await Task.WhenAny(imageTasks);
        imageTasks.Remove(imageTask);

        Bitmap image = await imageTask;
        panel.AddImage(image);
    }
    catch{}
}

Wouldn't this code be pretty inefficient? I am under the assumption that once Task.WhenAll's first task completes it then sets the other tasks in the list to "RanToCompletion" or "Cancelled" or some other status that would kill the progress of the other tasks. So even if it was only 2 tasks in the list to download images as in this example and 1 image was 2MB and the other one 4MB, more than likely the 2MB image would finish first (and 2ish MB or the other one would be received). It would then remove the 2MB from the list and start the loop over. Which seems like it would then start the 4MB download again, essentially wasting the progress already made, correct??

Upvotes: 1

Views: 450

Answers (1)

vtortola
vtortola

Reputation: 35905

All image downloads are executed in parallel at the same time in the instant you call 'GetBitmapAsync'.

The loop just checks which ones are done and add them to the panel. This way you can see the images as soon as they arrived.

Once a task ends, it does not affect the status of the other tasks.

Upvotes: 1

Related Questions