67 lines
2.1 KiB
Plaintext
67 lines
2.1 KiB
Plaintext
![]() |
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.
|
||
|
|
||
|
[frame=all]
|
||
|
[cols="^1,^1,^1"]
|
||
|
|===
|
||
|
|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++``
|
||
|
|===
|
||
|
|
||
|
// If you want to factorize the description uncomment the following line and create the file.
|
||
|
//include::../description.adoc[]
|
||
|
|
||
|
== Noncompliant Code Example
|
||
|
|
||
|
[source,csharp]
|
||
|
----
|
||
|
|
||
|
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
|
||
|
|
||
|
[source,csharp]
|
||
|
----
|
||
|
|
||
|
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
|
||
|
|
||
|
* https://msdn.microsoft.com/en-us/magazine/jj991977.aspx[Async/Await - Best Practices in Asynchronous Programming]
|
||
|
* https://docs.microsoft.com/en-us/azure/azure-functions/performance-reliability#use-async-code-but-avoid-blocking-calls[Improve the performance and reliability of Azure Functions - Scalability best practices]
|
||
|
* S4462 - a more generic rule about detecting blocking calls to ``++async++`` methods.
|
||
|
|
||
|
ifdef::env-github,rspecator-view[]
|
||
|
|
||
|
'''
|
||
|
== Implementation Specification
|
||
|
(visible only on this page)
|
||
|
|
||
|
The implementation should be common with S4462. When implementing, should make sure S4462 will ignore Azure Functions.
|