web-dev-qa-db-ja.com

TaskCompletionSource:SetResult()とTrySetResult()などを使用する場合

TPL、C#5の新しいasync/await機能、およびTaskCompletionSourceの謎に頭を抱えようとしています。

SetResultSetExceptionSetCancelTrySetResultTrySetExceptionTrySetCancelのどちらを使用するかは、私には明確ではありません。

これは、MSDNが言わなければならないことです。

タスクがすでに3つの最終状態(RanToCompletion、Faulted、またはCancelled)のいずれかにある場合、この操作はfalseを返します。

このメソッドは、基になるTaskがすでに破棄されている場合もfalseを返します。

わかりましたが、実際にいつどのように使用するかについてのガイダンスはありません。

だから、契約は何ですか?

52
HolySamosa

I suspectポイントは、結果を設定するものが1つしかない場合は、SetResultなどを呼び出すだけです。SetResultを2回呼び出すと、バグ。 (TaskCompletionSourceが破棄された場合も同様です。)

同時に結果を設定しようとする可能性のある複数のスレッドがある場合(たとえば、複数の並列Webサービス呼び出しからの最初の結果を示すためにそこにある)、完全に合理的であるため、TrySetResultを使用します。複数のスレッドが結果を設定するために「試行」する場合、別のスレッドがすでに設定しているかどうかに気づかない。

それに関する公式のガイダンスは見たことがありませんが、それは理にかなっています。

62
Jon Skeet