Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I thought TaskEx.WhenAll would return when all the tasks gets finished which is passed within the method. So await on TaskEx.WhenAll would return the array of Return statements, such that when every object gets finished, the array will be returned.

But it is not so. When I do :

    public async Task AsynchronousCallServerMordernParallelAsync()
        List<Task<string>> lstTasks = new List<Task<string>>();
        StringBuilder builder = new StringBuilder();
        for (int i = 2; i <= 10; i++)
            using (WebClient client = new WebClient())
                    this.tbStatus.Text = string.Format("Calling Server [{0}]..... ", i);
                    string currentCall = string.Format(Feed, i);
                    Task<string> task = client.DownloadStringTaskAsync(new Uri(currentCall));
                    lstTasks.Add(task);
                catch (Exception ex)
                    this.tbStatus.Text = string.Format("Error Occurred -- {0} for call :{1}, Trying next", ex.Message, i);
            string[] rss = await TaskEx.WhenAll<string>(lstTasks);
            foreach(string s in rss)
                builder.Append(s);
            MessageBox.Show(string.Format("Downloaded Successfully!!! Total Size : {0} chars.", builder.Length));

I see my MessageBox appears more than once, and also await steps in with array of 1 element, then array of 2 element and so on.

Can anyone tell me what exactly the nature of TakEx.WhenAll?

The call to TaskEx.WhenAll occurs inside the for loop. You have to put it outside.

public static async Task AsynchronousCallServerMordernParallelAsync()
        List<Task<string>> lstTasks = new List<Task<string>>();
        StringBuilder builder = new StringBuilder();
        for (int i = 2; i <= 10; i++)
            using (WebClient client = new WebClient())
                    Console.WriteLine("Calling server...");
                    Task<string> task = client.DownloadStringTaskAsync(new Uri("http://www.msn.com"));
                    lstTasks.Add(task);
                catch (Exception ex)
                    Console.WriteLine("Error occurred!");
        string[] rss = await TaskEx.WhenAll<string>(lstTasks);
        foreach (string s in rss)
            builder.Append(s);
        Console.WriteLine("Downloaded!");

WhenAll() create a tasks that completes when all the sub tasks complete. So, the method itself will not complete, but the task will.

It is a method that creates a new task that aggregates the separate task into a new, larger task.

I know that from the documentation, but the problem is, if I put await just before the TaskEx.WhenAll, it returns the array after every Task in the list gets finished. Is it a bug? – abhishek Nov 13, 2010 at 21:29 I am actually getting the MesssageBox more than once, so even though all the tasks are not finished, it gets the array of string for me. – abhishek Nov 13, 2010 at 21:30 Ah, I see now. You have to move the WhenAll call and all the lines after that outside of your for loop. Try that and see whether it helps. – Pieter van Ginkel Nov 13, 2010 at 21:33 Yes, thats exactly the problem is. Sorry for interrupting. I was actually surprised to see the output. The culprit is when I put the Using block around WebClient, which make me overlook the extra bracket. The problem is fixed now. Thank you – abhishek Nov 13, 2010 at 21:35

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.