.NET Fiddle

CSharp · Console

/Program.cs

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
					
public class Program
{
	public delegate void SimpleDelegate();
	public static SimpleDelegate OnDelegateInvoke;
	
	public delegate Task SimpleAsyncDelegate();
	public static SimpleAsyncDelegate OnAsyncDelegateInvoke;
	
	private static Random _rng = new Random();
	
	public static async Task Main()
	{
		OnDelegateInvoke += DelayedMessage;
		OnDelegateInvoke += DelayedMessage;
		OnDelegateInvoke += DelayedMessage;
		OnDelegateInvoke += DelayedMessage;
		OnDelegateInvoke += DelayedMessage;
		
		Console.WriteLine("=========================");
		Console.WriteLine("Start without await");
		Console.WriteLine("=========================");
		OnDelegateInvoke.Invoke();
		Console.WriteLine("Done invoking non-async");
		Thread.Sleep(5000); // Make sure all delegates are finished
		
		
		OnAsyncDelegateInvoke += DelayedMessageAsync;
		OnAsyncDelegateInvoke += DelayedMessageAsync;
		OnAsyncDelegateInvoke += DelayedMessageAsync;
		OnAsyncDelegateInvoke += DelayedMessageAsync;
		OnAsyncDelegateInvoke += DelayedMessageAsync;
		
		Console.WriteLine("=========================");
		Console.WriteLine("Start with await");
		Console.WriteLine("=========================");
		var delegateTasks = OnAsyncDelegateInvoke.GetInvocationList()
			.Cast<SimpleAsyncDelegate>()
			.Select(del => del.Invoke());
		await Task.WhenAll(delegateTasks);
		Console.WriteLine("Done invoking async");
	}
	
	private static async void DelayedMessage() // Still async, but not awaitable (void return type)
	{
		await Task.Delay(_rng.Next(1000));
		Console.WriteLine("I'm done!");
	}
	
	private static async Task DelayedMessageAsync()
	{
		await Task.Delay(_rng.Next(1000));
		Console.WriteLine("I'm done!");
	}
}
;