Wie kann ich eine TaskTask zum Abwickeln erzeugen?

8

Kann jemand bitte den Unterschied zwischen diesen beiden Aussagen erklären:

%Vor%

vs

%Vor%

Die Methoden ExtractArchiveAsync() , BackupCurrentDatabaseAsync() , RestoreDatabaseAsync() alle geben Task zurück.

Hier gibt die erste Fortsetzung ein Task<Task> zurück. Ich kann dann Unwrap() diese Aufgabe setzen, um Continuations auf die resultierende (innere) Aufgabe zu setzen.

Die zweite Version kompiliert nicht. Der einzige Unterschied hier sind die Klammern um die CompressArchiveAsync() .

Ich versuche auf die resultierende (interne) Task zuzugreifen, um die Task.Status zu überprüfen. Wenn ich die zweite Methode verwende, meldet Task.Status das Ergebnis der Aufgabe BackupCurrentDatabaseAsync() .

    
Simon 17.12.2014, 16:13
quelle

4 Antworten

11
%Vor%

entspricht:

%Vor%

Beachten Sie die return .

Ihr zweites Code-Snippet kompiliert nicht, weil ContinueWith kein Task<Task> zurückgibt, sondern einfach ein Task , und es gibt nichts zu entpacken.

Folgendes ist an ein Func<Task, Task> gebunden (eine Funktion, die ein Task übernimmt und ein Task zurückgibt)

%Vor%

Aber das Folgende ist tatsächlich an ein Action<Task> gebunden (eine Funktion, die ein Task übernimmt, aber nichts zurückgibt):

%Vor%

Und der Verweis auf Task , der von CompressArchiveAsync erstellt wurde, wird nie zurückgegeben. Ohne einen Verweis darauf können Sie den Status von Task nicht überprüfen.

Beachten Sie Folgendes:

Daher gibt Ihre ContinueWith(Func<Task, Task>) eine Task<Task> zurück, die Sie auspacken können, aber Ihre ContinueWith(Action<Task>) gibt einfach eine Task zurück.

    
Lucas Trzesniewski 17.12.2014, 16:18
quelle
3

Der Unterschied liegt in der Syntax des Lambda-Ausdrucks.

Es gibt zwei Arten von Lambdas: Expression Lambdas und Statement Lambdas . Ausdruck Lambdas haben keine geschweiften Klammern und geben das Ergebnis des Ausdrucks zurück, während Anweisung Lambdas geschweifte Klammern enthält, die keine oder mehrere Anweisungen enthalten (eine davon kann eine return -Anweisung sein).

Also dieser Ausdruck Lambda:

%Vor%

Entspricht dieser Aussage Lambda:

%Vor%

Der Unterschied besteht also darin, dass Sie in der ersten Folge eine Aufgabe zurückgeben, aber in der zweiten nicht, es ist nur ein void anonymer Delegierter. Deshalb ist die erste Fortsetzung ein Task<Task> , während die zweite nur ein Task ist.

    
i3arnon 17.12.2014 16:18
quelle
2

Langer Kommentar, um den Code 4.5 anzuzeigen.

Wenn Sie zu .Net 4.5 wechseln könnten, dann könnte Code, den Sie zu schreiben versuchen, kompakter mit async / await umgeschrieben werden, was im Wesentlichen den ganzen Code intern implementiert:

%Vor%     
Alexei Levenkov 17.12.2014 16:34
quelle
1

Im ersten Beispiel rufen Sie ContinueWith mit einem Func auf. Daher wird ein Task<T> zurückgegeben. Der zweite Versuch wird ContinueWith overload mit Action aufrufen, weil ... nun, es ist eine Aktion, es gibt nichts zurück. Es wird also ein einfaches Task ohne T zurückgegeben.

    
nvoigt 17.12.2014 16:19
quelle