Azure Functions Synchronous operations are disallowed Why?

Viewed 4339

I am working on two functions in Azure Functions

Timer Function and Http Trigger Function

My timer functions runs every 1 hour and it executes the http function via an Http Client.

Now I do get an error Synchronous operations are disallowed

And I know how to solve this using the article on stack overflow

But I am curious as why am I getting this error?

Whats the cause of it?

The error doesn't occur when using Postman.

My Timer Code

Azure Functions Core Tools (3.0.2245 Commit hash: 1d094e2f3ef79b9a478a1621ea7ec3f93ac1910d)
Function Runtime Version: 3.0.13139.0

 Host configuration file read:
{
   "version": "2.0"
}
public static class DoSomeStuffTimer
    {
        [FunctionName("DoSomeStuffTimer")]
        public static void Run([TimerTrigger("0 0 7 * * *")]TimerInfo myTimer, ILogger log)
        {
            try
            {
                log.LogInformation($"C# DoSomeStuffTimer executing at: {DateTime.Now}");
                string url = Environment.GetEnvironmentVariable(EnvironmentKey.HostKey) + "/api/DoSomeStuff";
                HttpClient client = new HttpClient();
                client.PostAsJsonAsync(url, new DoSomeStuffRequest());
                log.LogInformation($"C# DoSomeStuffTimer executed at: {DateTime.Now}");
            }
            catch (Exception e)
            {
                log.LogInformation(e.ToString());
            }
        }
    }

My Http Code

public class DoSomeStuffFunction
    {
        [FunctionName("DoSomeStuffFunction")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "DoSomeStuff")]
            HttpRequestMessage req,
            ILogger log)
        {
            var response = new ContentResult {ContentType = "application/json", StatusCode = 200};

            try
            {
                DoSomeStuffRequest
                    request = req.Content.ReadAsAsync<DoSomeStuffRequest>().Result;
    }
catch (Exception e)
            {
                log.LogInformation(e.ToString());
            }
}
}

2 Answers

Starting with ASP.NET Core 3.0 synchronous calls are disabled by default So any function running on 3.0 will encounter this when it tries to do synchronous calls

I looked into it and found the reason why it happens in your function is that ReadAsAsync<>() somewhere in it's operation does something synchronously. I am not sure exactly why it does this or why it doesn't break when you call the httptrigger directly. That'll require quite a bit more work to figure out.

To make your code work without FUNCTIONS_V2_COMPATIBILITY_MODE set to True you can use one of the other readers, for example ReadAsStreamAsync() instead.

Below you can find the method that works (I tested it locally). However, I would not recommend you call another function in your function app directly and instead follow the recommendations by Microsoft or create an abstraction that contains the logic that both functions can call on independently.

public class DoSomeStuffFunction
{
    [FunctionName("DoSomeStuffFunction")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = "DoSomeStuff")]
        HttpRequestMessage req,
        ILogger log)
    {
        var response = new ContentResult { ContentType = "application/json", StatusCode = 200 };

        try
        {
            var request = await req.Content.ReadAsStreamAsync();
            using (StreamReader rd = new StreamReader(request))
            {
                var result = JsonConvert.DeserializeObject<DoSomeStuffRequest>(await rd.ReadToEndAsync()).;
            }

            return new OkObjectResult(response);
        }
        catch (Exception e)
        {
            log.LogInformation(e.ToString());
            return new BadRequestObjectResult("It went wrong");
        }
    }
}

The solution you mentioned is to set the variable FUNCTIONS_V2_COMPATIBILITY_MODE to true. We can see some information about this variable in this page.

enter image description here

So,did you do the operation to upgraded your function from v2 to v3 ? It may cause this issue.

Update:

I test it in my side on local visual studio. When I create the function app in visual studio, I choose azure function v3(.net core). And below is my code, it works fine without any error.

namespace FunctionApp8
{
    public static class Function2
    {
        [FunctionName("Function2")]
        public static void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
            string url = "http://localhost:7071/api/triggerFunction";
            HttpClient client = new HttpClient();
            client.PostAsJsonAsync(url, "");
            log.LogInformation($"C# DoSomeStuffTimer executed at: {DateTime.Now}");
        }
    }
}
namespace FunctionApp8
{
    public static class Function1
    {
        [FunctionName("triggerFunction")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            return (ActionResult)new OkObjectResult($"Hello");
        }
    }
}

I'm not sure if your function app is related to .net core 2.x. So could you please follow the steps recreate another function app(check if your visual studio has been updated to the lastest version and choose Azure Function v3 .NET core at the beginning) and test if it works fine.

Related