【问题标题】:Why doesn't AsyncUnaryCall<T> and others extend Task<T>?为什么 AsyncUnaryCall<T> 和其他人不扩展 Task<T>?
【发布时间】:2019-02-14 06:29:18
【问题描述】:

在 C# 中使用 gRPC 时,异步调用返回 AsyncUnaryCall&lt;T&gt;(对于一元调用 - 当然,其他调用的返回类型略有不同)。但是,AsyncUnaryCall&lt;T&gt; 不会扩展 Task&lt;T&gt;。因此,您通常使用Task&lt;T&gt; 执行的常见操作不适用于AsyncUnaryCall&lt;T&gt;。这包括:

  • 指定延续策略(使用ConfigureAwait
  • 使用像 Task.WhenAnyTask.WhenAll 这样的助手

后者现在对我很不利,因为我想启动多个 gRPC 调用并等待它们全部完成。看来我唯一的办法就是写一个小助手,一个接一个地等待。

为什么AsyncUnaryCall&lt;T&gt; 不反映Task&lt;T&gt; 中的功能?

【问题讨论】:

  • looks like 它公开了单独的Tasks 的标题和完整的响应(请参阅ResponseAsyncResponseHeadersAsync)。为什么这些还不够?
  • 你不一定需要Task来应用await的东西,该类型只需要实现AsyncUnaryCall所做的awaitable/awaiter模式。
  • 你可以传入call.ResponseAsync。或者,对于几个:await Task.WhenAll(calls.Select(x =&gt; x.ResponseAsync));
  • 很好,不知何故我在探索 API 时错过了这一点。谢谢。
  • 我仍然不清楚的一件事是,我是否应该为我拨打的每个电话取消引用 ResponseAsync,以便我可以 ConfigureAwait(false) 处理它。

标签: c# asynchronous task-parallel-library grpc


【解决方案1】:

正如我在评论中所说,虽然它“类似任务”,但实际上是 represents two separate Tasks。如果您想使用个人 Tasks as Tasks,只需访问相应的属性(例如 ResponseHeadersAsyncResponseAsync)。

如果您有 List&lt;AsyncUnaryCall&lt;T&gt;&gt; 类型的变量 themAll,那么使用 WhenAll/WhenAny 很容易:

await Task.WhenAny(themAll.Select(c=>c.ResponseHeadersAsync));

如果你有有用的工作,你可以在任何标题到达时做,或者

await Task.WhenAll(themAll.Select(c=>c.ResponseAsync));

如果您在完成之前无法做任何有用的事情。作为两个例子。同样,如果您愿意,您可以提取其中一项任务并将其用于awaitConfigureAwait

【讨论】:

    猜你喜欢
    • 2013-03-25
    • 2015-02-12
    • 2014-05-06
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多