I have a azure function connected to a singnalr service that why IAsyncCollector paramter is used to add the return via AddAsync. Now I have to call a async method to calculate the result but so I need to change the method signature to async but then I also have to change the result to Task what is not working at runtime.
[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 }
});
}
I read about how IAsyncCollector collector work, so awaitig AddAsync make no sense. But how can I call that async method or make IAsyncCollector work in an async method. I not really found some sample how this may work. There are some samples in ms doc but they have no return or do not use async.
AddAsync
is a Task
returning method. Since your function is already async
, you should be await
ing the value.
The way your function is currently written you are returning a Task<Task>
. The azure function runtime will wait for the outer task, but will basically discard the inner one. That outer task completes practically instantly since it's only work is to create another task. This means that the Task
returned from the AddAsync
operation will be discarded and will likely have not completed before the infrastructure calls Flush
on the collector. This will therefore result in the loss of the collected value.
I'm not sure why you are under the impression that you shouldn't await
the method. I suspect you ended up with the Task<Task>
return type because of this assumption*.
The correct way to implement this is to have your function return a Task
and to await
the AddAsync
call:
// 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 }
});
}
* As opposed to you starting out with the return type of Task<Task>
already selected and determining the only way to make that happen was to return the Task
from AddAsync
without await
ing it.