C# Async await best practices

Don’t use async void

An async method may return Task, Task<T> and void. Natural return types are all but void.

Any sync method returning void becomes an async method returning Task. example:

// synchronous work
void MyMethod()
{
	Thread.sleep(1000);
}

// asynchronous work
async Task MyAsyncMethod()
{
	await Task.Delay(1000);
}

When an exception is thrown out of an async Task or async Task<T> method that exception is captured and placed on the Task object. For async void methods, exceptions aren’t caught.

example:

private async void ThrowExceptionAsync()
{
	throw new InvalidOperationException();
}

public void AsyncVoidExceptions_CannotBeCaught()
{
	try
	{
		ThrowExceptionAsync();
	}
	catch(Exception)
	{
		// The exception is never caught here!
		throw;
	}
}

The exception to use async void are asynchronous event handlers.

example:

private async void button1_clicl(object sender, EventArgs e)
{
	await Button1ClickAsync(); // my method
}

Reference(s)

https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming