2012-08-23 5 views
37

Ich versuche, meinen Kopf rund um die TPL, die neuen async/await Funktionen in C# 5 und die Geheimnisse von TaskCompletionSource.TaskCompletionSource: Wann SetResult() im Vergleich zu TrySetResult(), etc.

Eine Sache, die mir nicht klar ist, ist, wenn SetResult zu verwenden, SetException und SetCancel gegen TrySetResult, TrySetException und TrySetCancel.

Dies ist, was MSDN zu sagen hat:

Dieser Vorgang falsch zurück, wenn die Aufgabe ist bereits in einer der drei Endzustände: RanToCompletion, Faulted oder Abgebrochen.

Diese Methode gibt auch false zurück, wenn der zugrunde liegende Task bereits entsorgt wurde.

Ok, ich verstehe das, aber es gibt keine Anleitung darüber, wann oder warum man das eine über das andere verwendet.

Also, was ist das Geschäft?

Antwort

46

I Verdächtiger der Punkt ist, dass, wenn es nur eine Sache, die das Ergebnis wird Einstellung, rufen Sie einfach SetResult etc. Wenn Sie SetResult zweimal am Ende Aufruf, das einen Fehler anzeigt. (Wenn die TaskCompletionSource ebenfalls entsorgt wurde.)

Wenn Sie mehrere Threads haben, die alle gleichzeitig versuchen könnten, das Ergebnis zu setzen (z. B. um das erste Ergebnis mehrerer paralleler Web-Service-Aufrufe anzuzeigen)) Verwenden Sie dann TrySetResult, da es durchaus sinnvoll ist, dass mehrere Threads "versuchen", das Ergebnis festzulegen, ohne zu wissen, ob ein anderer Thread es bereits festgelegt hat.

Ich habe keine offizielle Anleitung dazu gesehen, aber das würde Sinn machen.

+8

d. H. Wirklich, der einzige Grund, warum Sie 'TrySetResult' aufrufen müssen, ist, wenn Sie das Ergebnis mehr als einmal einstellen. 'SetResult'" schließt "die zugehörige' Task' ab, so dass '' SetResult' 'erneut aufgerufen wird, um das 'Task ''s Ergebnis zu setzen, nachdem die Task abgeschlossen ist. ('SetResult' blockiert bis zum' Task' - wie auch 'TrySetResult') Wenn Sie' SetResult' nur einmal aufrufen, sollten Sie niemals 'TrySetResult' benötigen. FWIW. 'SetResult' Ketten zu' TrySetResult' ... –

+0

Danke Jungs, Sie machen eine Menge Sinn! – HolySamosa

+0

Beachten Sie auch, dass SetResult 'void' zurückgibt, während TrySetResult' bool' zurückgibt. Wenn Sie also abhängig vom Task-Status etwas tun möchten, wird 'TrySetResult' gleichzeitig überprüft und gesetzt (atomar?). – chakrit