Как вызвать асинхронные методы из функции azure, подключенной к службе singnalr, почему IAsyncCollector используется для возврата

У меня есть функция azure, подключенная к службе singnalr, поэтому параметр IAsyncCollector используется для добавления возврата через AddAsync. Теперь мне нужно вызвать асинхронный метод для вычисления результата, но мне нужно изменить сигнатуру метода на async, но тогда мне также нужно изменить результат на Task, который не работает во время выполнения.

[FunctionName("Join")]
public static async Task<Task> Join(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] JoinRequest message,
            [SignalR(HubName = "chat")] IAsyncCollector<SignalRMessage> signalRMessages)
{
    await MyHelper.Instance.FillAsync(message);           
    return signalRMessages.AddAsync(
        new SignalRMessage
                {
                    Target = "joined",
                    Arguments = new[] { message }
                });
}

Я читал о том, как работает сборщик IAsyncCollector, поэтому ждать AddAsync не имеет смысла. Но как я могу вызвать этот асинхронный метод или заставить IAsyncCollector работать в асинхронном методе. Я действительно не нашел образца, как это может работать. В ms doc есть несколько примеров, но они не возвращаются или не используют async.

1 ответ

Решение

AddAsync это Taskметод возврата. Поскольку ваша функция ужеasyncты должен быть awaitзначение.

То, как ваша функция в настоящее время написана, вы возвращаете Task<Task>. Среда выполнения функции Azure будет ждать внешней задачи, но в основном отбрасывает внутреннюю. Эта внешняя задача завершается практически мгновенно, так как работа заключается только в создании другой задачи. Это означает, чтоTask вернулся из AddAsync операция будет отменена и, вероятно, не будет завершена до вызова инфраструктуры Flushна коллекторе. Следовательно, это приведет к потере собранной стоимости.

Я не уверен, почему вы думаете, что не должны awaitметод. Я подозреваю, что вы закончилиTask<Task> возвращаемый тип из-за этого предположения *.

Правильный способ реализовать это - заставить вашу функцию возвращать Task и чтобы await в AddAsync вызов:

// returns Task not Task<Task>
[FunctionName("Join")]
public static async Task Join(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post")] JoinRequest message,
            [SignalR(HubName = "chat")] IAsyncCollector<SignalRMessage> signalRMessages)
{
    await MyHelper.Instance.FillAsync(message)
    // no return, await the call       
    await signalRMessages.AddAsync(
        new SignalRMessage
                {
                    Target = "joined",
                    Arguments = new[] { message }
                });
}

* В отличие от того, что вы начинаете с возвращаемого типаTask<Task> уже выбран и определил, что единственный способ сделать это - вернуть Task от AddAsync без awaitэто.

Другие вопросы по тегам