org.sonar.plugins.csharp.S6422.html Maven / Gradle / Ivy
Why is this an issue?
Making blocking calls to async
methods transforms the code into a
synchronous operation. Doing so inside an Azure Function can lead to thread pool exhaustion.
Thread pool exhaustion refers to a situation where all available threads in a thread pool are occupied, and new tasks or work items cannot be
scheduled for execution due to the lack of available threads. This can lead to delayed execution and degraded performance.
class RequestParser
{
[FunctionName(nameof(ParseRequest))]
public static async Task<IActionResult> ParseRequest([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...
}
}
Instead, asynchronous mechanisms should be used:
class RequestParser
{
[FunctionName(nameof(ParseRequest))]
public static async Task<IActionResult> ParseRequest([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req)
{
// Non-blocking, asynchronous operation
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
// do stuff...
}
}
This applies to multiple methods that are available when working with tasks:
Goal
Blocking
Asynchronous
Wait for the result of a task
Task.Wait
, Task.Result
or Task.GetAwaiter.GetResult
await
Wait for any of many task to complete
Task.WaitAny
await Task.WhenAny
Wait for all of many tasks to complete
Task.WaitAll
await Task.WhenAll
Wait a period of time
Thread.Sleep
await Task.Delay
Resources
Documentation
- Microsoft Learn - Async/Await - Best
Practices in Asynchronous Programming
- Microsoft Learn - Improve the
performance and reliability of Azure Functions - Scalability best practices
- Github - Async Guidance by David Fowler
- {rule:csharpsquid:S4462} - Calls to "async" methods should not be blocking (a more general version of this rule)