Azure Функции Синхронные операции запрещены. Почему? - PullRequest
1 голос
/ 19 марта 2020

Я работаю над двумя функциями в Azure Функции

Timer Function и Http Trigger Function

Мои функции таймера запускаются каждые 1 час и выполняют функцию http через Http-клиент .

Теперь я получаю сообщение об ошибке Синхронные операции запрещены

И я знаю, как решить эту проблему, используя статью при переполнении стека

Но мне любопытно, почему я получаю эту ошибку?

В чем причина?

Ошибка не возникает при использовании Почтальона.

Мой код таймера

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

Ответы [ 2 ]

0 голосов
/ 19 марта 2020

Начиная с ASP. NET Core 3.0 синхронные вызовы по умолчанию отключены Поэтому любая функция, работающая в 3.0, столкнется с этим при попытке выполнить синхронные вызовы

Я посмотрел и обнаружил причину, по которой это происходит в вашей функции, в том, что ReadAsAsync<>() где-то в своей работе делает что-то синхронно. Я не уверен точно, почему он это делает или почему он не ломается, когда вы вызываете httptrigger напрямую. Это потребует немного больше работы, чтобы выяснить.

Чтобы ваш код работал без FUNCTIONS_V2_COMPATIBILITY_MODE, установленного на True, вы можете использовать один из других считывателей, например ReadAsStreamAsyn c ().

Ниже вы можете найти метод, который работает (я проверял это локально). Однако я бы не рекомендовал вам напрямую вызывать другую функцию в своем приложении функций и вместо этого следовать рекомендациям от Microsoft или создавать абстракцию, содержащую логику c, которую обе функции могут вызывать независимо.

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");
        }
    }
}
0 голосов
/ 19 марта 2020

Упомянутое вами решение состоит в том, чтобы установить для переменной FUNCTIONS_V2_COMPATIBILITY_MODE значение true. Мы можем видеть некоторую информацию об этой переменной на этой странице .

enter image description here

Итак, вы выполнили операцию по обновлению вашей функции? с 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 в начале ) и проверить, если оно отлично работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...