Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for Tasks to finish

Tags:

c#

async-await

I have 2 simple methods and I want process to not continue until they are finished completely. Because of this I used await Task.WaitAll(tasks); but compiler is giving me error in this line:

Severity    Code    Description Project File    Line    Suppression State
Error   CS1503  Argument 1: cannot convert from ' 
'System.Collections.Generic.List<System.Threading.Tasks.Task>' to 
'System.Threading.Tasks.Task'   

Why should I convert this manually by myself? I thought this would be done by the compiler...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

internal class Program
{
    public static void Count1()
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Count 1 " + i);
            Thread.Sleep(100);
        }
    }

    public static void Count2()
    {
        for (int i = 0; i < 20; i++)
        {
            Console.WriteLine("Count 2 " + i);
            Thread.Sleep(100);
        }
    }

    public static async Task Run()
    {
        List<Task> tasks = new List<Task>();

        Task t1 = Task.Run(()=>Count1());
        Task t2 = Task.Run(() => Count2());

        tasks.Add(t1);
        tasks.Add(t2);

        await Task.WaitAll(tasks);  //ERROR IS THROWN HERE
    }

    private static void Main(string[] args)
    {
        Run();

        Console.ReadKey();
    }
}
like image 735
Lyrk Avatar asked Jul 31 '17 13:07

Lyrk


2 Answers

I suspect you meant WhenAll rather than WaitAll. WaitAll is a blocking call that returns all the results synchronously, when the original tasks have completed. You can't await that result, as it's not a task.

WhenAll is an asynchronous call that returns a task which completes when all the original tasks have completed. You can await that.

If you change the end of your Run method to:

await Task.WhenAll(tasks);
Console.WriteLine("All tasks completed");

... you'll see the tasks finish and then the completion message.

like image 105
Jon Skeet Avatar answered Sep 17 '22 14:09

Jon Skeet


You can use it as :

Task.WaitAll(tasks.ToArray());
  • Requires params of Task, so you have to use toArray() of linQ.
  • or you can also use : Task.WhenAll(t1, t2); as @Jon Skeet suggested.

The main difference between Task.WaitAll and Task.WhenAll is that the former will block (similar to using Wait on a single task) while the latter will not and can be awaited, yielding control back to the caller until all tasks finish.

For More Detail : You Can see here.

like image 38
Tapas Thakkar Avatar answered Sep 16 '22 14:09

Tapas Thakkar