1

I'm tasked with creating REST APIs with Azure Functions in .NET Core 2.1+, but I'm concerned about deadlocks. We'll have an on-site party that will calling the APIs for POST requests using a JavaScript framework, and other off-site parties that are making POST requests and using it in some other way. Stephen Cleary says here - Is .GetAwaiter().GetResult(); safe for general use? - that Azure functions always run code without a context. Stephen says here - https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html - that ASP.NET Core apps don't use the same SynchronizationContext used by legacy ASP.NET. He says blocking async code won't deadlock since it's running on the thread pool thread, so there's no reason to use ConfigureAwait(false). But you should use ConfigureAwait(false) if you're writing core libraries that are reused in non-ASP.NET Core applications. Since Azure function-based REST APIs have no context and are stand-alone, is there a need for preventing deadlocks with ConfigureAwait(false)?

EDIT: I have code that looks like this:

private readonly ILogger<AzureMockFunctions> _logger;

    public AzureMockFunctions(ILogger<AzureMockFunctions> logger)
    {
        _logger = logger;
    }

[FunctionName("Function")]
    public Task<ActionResult<Teacher>> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "null")] HttpRequest request)
    {
        try
        {
            _logger.LogInformation("C# HTTP trigger function processed a request.");

            using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8))
            {
                string requestBody = reader.ReadToEndAsync().GetAwaiter().GetResult();
                Teacher data = JsonConvert.DeserializeObject<Teacher>(requestBody);

                if (data == null)
                    throw new Exception("request body is empty");
            }

            Teacher teacher = new Teacher
            {
                prop1 = "some string",
                prop2 = "1",
                prop3 = "some other string"
            };                

            return Teacher;
        }
        catch (Exception ex)
        {
            _logger.LogError($"An error occurred: {ex}");

            return new BadRequestObjectResult(new
            {
                message = "An error occurred: " + ex.Message
            });
        }
    }

public class Teacher
{
    public string prop1{ get; set; }
    public string prop2{ get; set; }
    public string prop3{ get; set; }
}
  • Share your request code snippet. – Md Farid Uddin Kiron Sep 04 '19 at 15:49
  • 3
    ASP.NET Core does not have a `SynchronizationContext`. If you are on ASP.NET Core, it does not matter whether you use `ConfigureAwait(false)` or not. – Karan Sep 04 '19 at 15:52
  • Stephen Cleary says on his blog (the second link) - "I still recommend that you use it in your core libraries - anything that may be reused in other applications. If you have code in a library that may also run in a UI app, or legacy ASP.NET app, or anywhere else there may be a context, then you should still use ConfigureAwait(false) in that library." That's my question - since my .NET Core based Azure function/REST API is used by other applications that likely do use a context, do I need to add ConfigureAwait(false) to my async code? –  Sep 04 '19 at 15:54

1 Answers1

3

Regarding Stephen Cleary's admonition:

I still recommend that you use it in your core libraries - anything that may be reused in other applications. If you have code in a library that may also run in a UI app, or legacy ASP.NET app, or anywhere else there may be a context, then you should still use ConfigureAwait(false) in that library.

When he talks about "libraries", Stephen Cleary is talking about DLLs. When you are separating yourself from the caller via a REST API, then your code doesn't qualify as a "library" by this definition. If you're positive that your code will only ever be used in a .NET Core context, you can safely omit calls to .ContinueAwait(false).

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • That's exactly what I was thinking when I said stand-alone - thanks for the confirmation! –  Sep 05 '19 at 13:06