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()
	var taskList = new List<Task>();

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

// 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);

// 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);

// 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++)
			await Task.Delay(delay);

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