The example below runs in LinqPad but has not been tested in VS or VSCode.

The demonstration shows that tasks are started immediately, added to a list and then execution is paused until one, and later all, tasks have completed.

async Task Main()
{
	Debug.WriteLine("starting");
	var taskList = new List<Task>();

// first task is created...
	var t = TestTask.DoSomething("first", 100);
	taskList.Add(t);

// line below demonstrates that first task starts immediately.
// because will see results for 500ms before the next task starts
	await Task.Delay(500);

// now add a second task, which will also start immediately
	var t1 = TestTask.DoSomething("\t\t\t SECOND", 500);
	taskList.Add(t1);

// and add a third task, also to start immediately
	var t2 = TestTask.DoSomething("\t\t\t\t\t\t\t\t\t\t\t\t third", 1000);
	taskList.Add(t2);

// we don't have to create an intermediate variable, great for loops.... 
	taskList.Add(TestTask.DoSomething("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t fourth", 300));

	await Task.WhenAny(taskList);
	// the equivalent to above but not creating a task	
	// Task.WaitAny(taskList.ToArray());

	Debug.WriteLine("somebody is done - not sure which");

	await Task.WhenAll(taskList);
	// the equivalent to above but not creating a task	
	// Task.WaitAll(taskList.ToArray());
	
// the line below should appear when all tasks are finished.
	Debug.WriteLine("\n\n________________ all finished ______________");

}

public static class TestTask
{

	public static async Task DoSomething(string name, int delay)
	{
		for (int i = 0; i < 10; i++)
		{
			Debug.WriteLine($"{name}:{i}");
			await Task.Delay(delay);
		}
	}
}

// Define other methods and classes here
Sample Thread List with WhenAny and WhenAll