TaskCompletionSource:何时使用SetResult()与TrySetResult()等

Hol*_*osa 50 c# asynchronous task-parallel-library async-await c#-5.0

我想换我周围的TPL,新的头async/ await在C#5的特性,和的奥秘TaskCompletionSource.

有一件事情是我不明白是什么时候使用SetResult,SetException以及SetCancelTrySetResult,TrySetExceptionTrySetCancel.

这就是MSDN所说的:

如果任务已经处于以下三种最终状态之一,则此操作将返回false:RanToCompletion,Faulted或Cancelled.

如果已经处理了基础Task,则此方法也返回false.

好吧,我明白了,但它并没有真正提供关于何时或为何使用其中一个的指导.

那么,这笔交易是什么?

Jon*_*eet 66

怀疑的重点是,如果只有一件事将设置结果,只需要打电话SetResult等.如果你最终调用SetResult两次,那表明存在错误.(同样,如果TaskCompletionSource已被处置.)

如果你有几个线程可以同时尝试设置结果(例如它在那里指示几个并行web服务调用的第一个结果)然后使用TrySetResult,因为多线程"完全合理" "设置结果,不知道另一个线程是否已设置它.

我没有看到任何关于它的官方指导,但这是有道理的.

  • 即真的,你需要调用`TrySetResult`的唯一原因是你不止一次设置结果.`SetResult`"完成"关联的`Task`,因此再次调用`SetResult`将尝试在任务完成后设置`Task <T>`的结果.(`SetResult`阻塞,直到'Task`完成 - 就像`TrySetResult`一样)如果你只调用一次'SetResult`,那么你永远不需要`TrySetResult`.FWIW.`SetResult`链到`TrySetResult` ... (13认同)
  • 还要注意,SetResult返回`void`,而TrySetResult返回`bool',因此,如果您想根据任务状态有条件地执行某项操作,则`TrySetResult`会同时被检查和设置(在原子上?)。 (2认同)