【问题标题】:Azure Functions Synchronous operations are disallowed Why?不允许 Azure Functions 同步操作 为什么?
【发布时间】:2020-03-19 19:59:15
【问题描述】:

我正在研究 Azure Functions 中的两个函数

Timer FunctionHttp Trigger Function

我的计时器函数每 1 小时运行一次,它通过 Http 客户端执行 http 函数。

现在我确实收到了一个错误不允许同步操作

我知道如何在堆栈溢出时使用article 解决这个问题

但我很好奇为什么会出现这个错误?

这是什么原因?

使用 Postman 时不会出现该错误。

我的计时器代码

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());
            }
        }
    }

我的 Http 代码

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());
            }
}
}

【问题讨论】:

    标签: c# azure azure-functions


    【解决方案1】:

    从 ASP.NET Core 3.0 开始 synchronous calls are disabled by default 所以任何在 3.0 上运行的函数在尝试进行同步调用时都会遇到这个问题

    我对其进行了调查,发现它发生在您的函数中的原因是 ReadAsAsync&lt;&gt;() 在它的操作中的某个地方同步执行了某些操作。我不确定它为什么会这样做,或者当你直接调用 httptrigger 时为什么它不会中断。这需要更多的工作才能弄清楚。

    要使您的代码在 FUNCTIONS_V2_COMPATIBILITY_MODE 不设置为 True 的情况下工作,您可以使用其他读取器之一,例如 ReadAsStreamAsync()。

    您可以在下面找到有效的方法(我在本地测试过)。但是,我不建议您直接在函数应用中调用另一个函数,而是遵循 recommendations by Microsoft 或创建一个包含两个函数可以独立调用的逻辑的抽象。

    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");
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您提到的解决方案是将变量FUNCTIONS_V2_COMPATIBILITY_MODE 设置为true。我们可以在这个page 中看到关于这个变量的一些信息。

      那么,您是否进行了将您的功能从 v2 升级到 v3 的操作?这可能会导致此问题。

      更新:

      我在本地视觉工作室测试它。在 Visual Studio 中创建函数应用程序时,我选择 azure function v3(.net core)。下面是我的代码,它工作正常,没有任何错误。

      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");
              }
          }
      }
      

      我不确定您的函数应用是否与 .net core 2.x 相关。那么您能否按照步骤重新创建另一个函数应用(检查您的 Visual Studio 是否已更新到最新版本并在开始时选择 Azure Function v3 .NET core)并测试它是否正常工作。

      【讨论】:

      • 我的应用在 dotnet core 3.0 上运行,并且在主机中 json 版本设置为 2
      • 虽然我通过 Postman 触发时没有发生错误
      • @NoobCoder 请检查错误是否与定时器函数(定时器函数的运行时版本)有关。
      • @NoobCoder 据我所知,即使你创建了 v3 函数,host.json 中的版本也不会改变(参考这个tutorial)。它永远是 2.0。
      • @NoobCoder 我可以知道您的函数应用程序是否是过去创建的,然后当您从 Visual Studio 发布代码时,您会选择此函数应用程序吗?或者当你从 Visual Studio 发布代码时,你创建了一个新的函数应用?
      猜你喜欢
      • 2021-11-01
      • 1970-01-01
      • 2023-01-27
      • 1970-01-01
      • 2019-07-29
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多