【问题标题】:TaskCompletionSource : When to use SetResult() versus TrySetResult(), etcTaskCompletionSource :何时使用 SetResult() 与 TrySetResult() 等
【发布时间】:2012-08-19 11:08:40
【问题描述】:

我正试图围绕 TPL、C# 5 中的新 async / await 功能以及 TaskCompletionSource 的奥秘。

我不清楚的一件事是何时使用 SetResultSetExceptionSetCancelTrySetResultTrySetExceptionTrySetCancel

这是 MSDN 不得不说的:

如果Task已经在里面,这个操作会返回false 三种最终状态之一:RanToCompletion、Faulted 或 Canceled。

如果底层任务有这个方法也返回 false 已经被处理掉了。

好的,我明白了,但它并没有真正提供关于何时或为什么使用其中一个而不是另一个的任何指导。

那么,交易是什么?

【问题讨论】:

    标签: c# asynchronous task-parallel-library async-await c#-5.0


    【解决方案1】:

    除了 Jon 的回答之外,MS 文档门户网站还提到了 TrySetResult

    如果Task<TResult> 已经处于三种最终状态之一,则此操作将返回 false:

    • RanToCompletion
    • 故障
    • 已取消

    链接:https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.taskcompletionsource-1.trysetresult?view=net-5.0

    【讨论】:

      【解决方案2】:

      怀疑的重点是,如果只有一件事会设置结果,只需调用SetResult 等。如果您最终调用SetResult 两次,则表明存在错误。 (同样,如果 TaskCompletionSource 已被处置。)

      如果您有多个线程可能都试图同时设置结果(例如,它表示多个并行 Web 服务调用的第一个结果),那么使用TrySetResult,因为这是完全合理的让多个线程“尝试”设置结果,不知道是否另一个线程已经设置了它。

      我还没有看到任何官方指导,但这是有道理的。

      【讨论】:

      • 即实际上,您需要调用TrySetResult 的唯一原因是您是否多次设置结果。 SetResult“完成”关联的Task,因此再次调用SetResult 将尝试在任务完成后设置Task<T> 的结果。 (SetResult 阻塞直到 Task 完成——就像 TrySetResult 一样)如果你只调用一次 SetResult,那么你永远不需要 TrySetResult。 FWIW。 SetResult 链接到 TrySetResult...
      • 谢谢大家,你们说的很有道理!
      • 还要注意 SetResult 返回 void 而 TrySetResult 返回 bool 所以如果你想根据任务状态有条件地做某事,那么 TrySetResult 是同时检查和设置(原子?)。
      猜你喜欢
      • 2014-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-22
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多