Making blocking calls to async methods transforms code that was intended to be asynchronous into a blocking operation. Doing so inside an Azure Function can lead to thread exhaustion.

To Do This … Instead of This … Use This

Retrieve the result of a background task

Task.Wait, Task.Result or Task.GetAwaiter.GetResult

await

Wait for any task to complete

Task.WaitAny

await Task.WhenAny

Retrieve the results of multiple tasks

Task.WaitAll

await Task.WhenAll

Wait a period of time

Thread.Sleep

await Task.Delay

Noncompliant Code Example

public static class AvoidBlockingCalls
{
	[FunctionName("Foo")]
	public static async Task<IActionResult> Foo([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req)
	{
		// This can lead to thread exhaustion
		string requestBody = new StreamReader(req.Body).ReadToEndAsync().Result;

		// do stuff...
	}
}

Compliant Solution

public static class AvoidBlockingCalls
{
	[FunctionName("Foo")]
	public static async Task<IActionResult> Foo([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req)
	{
		string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

		// do stuff...
	}
}

See