When working with gRPC in C#, asynchronous calls return AsyncUnaryCall<T> (for unary calls - of course, other calls have slightly different return types). However, AsyncUnaryCall<T> does not extend Task<T>. Therefore, common things you would ordinarily do with a Task<T> do not work with AsyncUnaryCall<T>. This includes:
ConfigureAwait)Task.WhenAny and Task.WhenAll
The latter is biting me at the moment, since I want to kick off multiple gRPC calls and wait for them all to complete. It seems my only recourse is to write a little helper that awaits for one after the other.
Why doesn't AsyncUnaryCall<T> mirror the functionality in Task<T>?
As I said in a comment, whilst it's "Task-like", it actually represents two separate Tasks. If you want to work with the individual Tasks as Tasks, just access the appropriate property (e.g. ResponseHeadersAsync or ResponseAsync).
If you have a variable themAll of type List<AsyncUnaryCall<T>> then using WhenAll/WhenAny is easy:
await Task.WhenAny(themAll.Select(c=>c.ResponseHeadersAsync));
if you've got useful work you can do when any headers arrive, or
await Task.WhenAll(themAll.Select(c=>c.ResponseAsync));
if you can't do anything useful until they're all completed. As two examples. Similarly, you can extract one of these tasks and use it in an await with a ConfigureAwait, if you want to do so.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With