2

I want to run several tasks in async and wait for all of them to complete.

private static Task AddAFavicon(int id)
{
    // some operation where each task create excel sheet as per id.
}

static void Main(string[] args)
{
    // i have this main method which contain publications in list 
    XElement Publication = XElement.Load() // read publication from xml file.
    foreach (var item in Publication.Descendants())
    {
        //here i want to call this AddAFavicon method for each item as async task 
    }
    //wait for all task to complete 
}

I want to wait for all tasks to complete and then do my other stuff. thanks in advance :)

ketan patil
  • 65
  • 15

2 Answers2

4

You can use the method Task.WhenAll to wait for multiple async tasks to complete:

Task t1 = DoSomethingAsync1();
Task t2 = DoSomethingAsync2();
await Task.WhenAll(t1, t2);

In your specific case you can do something like:

List<Task> tasks = new List<Task>();
foreach (var item in Publication.Descendants())
{
    int id = 0; // TODO: Initialize properly.
    tasks.Add(AddAFavicon(id));
}
await Task.WaitAll(tasks);
wohlstad
  • 12,661
  • 10
  • 26
  • 39
  • hi thanks for valuable reply can please show how i can apply your code in my sample code :( – ketan patil Jan 11 '23 at 09:59
  • You are planning to call `AddAFavicon` in the loop. Each call will return a `Task` object. Keep them all in a list/array and then use `Task.WhenAll` to wait for them all to complete. – wohlstad Jan 11 '23 at 10:01
  • 1
    I replaced the "cold" tasks with an example more compliant with the OP's code. – wohlstad Jan 11 '23 at 10:06
-2

You can do await AddAFavIconAsync(); in your loop. It will wait for your current task to complete before going on the next item and doing the same action.

Note your code here is incomplete, an async function should have the async keyword in its declaration, if not you will not be able to await anything inside that method.

So you would have something more like :

private static async Task AddAFaviconAsync(int id)
{
    // some operation where each task create excel sheet as per id.
}

public static async Task Main(string[] args)
{
    // i have this main method which contain publications in list 
    XElement Publication = XElement.Load() // read publication from xml file.
    foreach (var item in Publication.Descendants())
        {
            await AddAFavIconAsync(item.id);
            //here i want to call this AddAFavicon method for each item as async task 
        }
}

You can also note that I added Async at the end of the method names. Its just a basic naming convention you should use :). Just not for the Main method (as shown here).

Scryper
  • 178
  • 1
  • 14
  • You could, but since you await each task you are not doing them asynchronously. – Taemyr Jan 11 '23 at 09:56
  • 3
    @Taemyr Yes you _are_ doing them asynchronously but not _concurrently_. – Fildor Jan 11 '23 at 09:58
  • @Fildor what's the difference between thoses two (asynchronously and concurrently) ? I also feel like I misunderstood the question, my bad. – Scryper Jan 11 '23 at 09:59
  • 2
    @Scryper : https://medium.com/plain-and-simple/synchronous-vs-asynchronous-vs-concurrent-vs-parallel-4342bfb8b9f2 – Fildor Jan 11 '23 at 10:01
  • No. You are adding a synchronization instruction (the await) between the tasks. So you are saying, start task 1, when that is finished start task 2, and so on. I.e. synchronously. Rather than start task 1 and task 2 and so on, and then waiting for all of them to finish. Your outer method returns a task, so you can do other things asynchronously with this method, but the method you have written runs synchronously. – Taemyr Jan 11 '23 at 10:02
  • 1
    No, @Taemyr. `await` does a lot more than that. It may or may not (assuming this is a "real" IO-Bound operation: it will) release the current Thread to do other things, waiting for the completion of the Task. That's the whole idea of that and **a**synchronous. Otherwise we just could have stuck to plain old Threads. – Fildor Jan 11 '23 at 10:07
  • 1
    Oh _that's_ what you mean ... it's still not synchronous. That would just be sequential. – Fildor Jan 11 '23 at 10:09
  • Agreed there is more going on, this does not change the fact that the method as written synchronizes it's tasks. – Taemyr Jan 11 '23 at 10:09
  • 1
    It's sequential, yes. But it does not block (the thread). – Fildor Jan 11 '23 at 10:10
  • Yes, you avoid blocking. But given that we see main I am not sure there is any benefit. (Nothing else for the thread to do) – Taemyr Jan 11 '23 at 10:12
  • Right. That's why OP seems to target for both: asynchronity _and_ concurrency. :D – Fildor Jan 11 '23 at 10:14
  • @Taemyr `async` / `await` makes the code _read_ like synchronous code. Once compiled, it is actually asynchronous. – Johnathan Barclay Jan 11 '23 at 10:35