首页 > 解决方案 > 如何从连接到 singnalr 服务的 azure 函数调用异步方法,为什么使用 IAsyncCollector 进行返回

问题描述

我有一个连接到 singnalr 服务的天蓝色函数,为什么 IAsyncCollector 参数用于通过 AddAsync 添加返回。现在我必须调用异步方法来计算结果,但是我需要将方法签名更改为异步,但我还必须将结果更改为在运行时不起作用的任务。

[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 收集器是如何工作的,所以 awaitig AddAsync 没有任何意义。但是我怎样才能调用该异步方法或使 IAsyncCollector 在异步方法中工作。我并没有真正找到一些示例,这可能是如何工作的。ms doc中有一些示例,但它们没有返回或不使用异步。

标签: c#async-awaitsignalrazure-functionssignalr-service

解决方案


AddAsync是一个Task返回方法。由于您的功能已经是async,您应该是await价值。

您当前编写函数的方式是返回一个Task<Task>. azure 函数运行时会等待外部任务,但基本上会丢弃内部任务。该外部任务几乎立即完成,因为它唯一的工作就是创建另一个任务。这意味着Task从操作返回的数据将被丢弃,并且可能在基础设施调用收集器AddAsync之前尚未完成。Flush因此,这将导致所收集价值的损失。

我不确定您为什么认为您不应该await使用该方法。我怀疑你最终得到了Task<Task>返回类型,因为这个假设*。

实现这一点的正确方法是让你的函数返回 a和Task调用:awaitAddAsync

// 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>开始并确定实现这一目标的唯一方法相反,是在不使用它的情况下返回Taskfrom 。AddAsyncawait


推荐阅读