asynchron warten auf Rückgabe Aufgabe


131

Kann jemand erklären, was dies für eine synchrone Methode bedeutet? Wenn ich versuche, die Methode zu ändernasync beschwert sich VS darüber.

Das funktioniert:

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

Das funktioniert nicht:

public async Task MethodName()
{
     return Task.FromResult<object>(null);
}

Im Grunde würde ich gerne wissen, was genau das bedeutet: Task.FromResult<object>(null);



@LB hmm das funktioniert! Aber auch wenn ich nur auch return;arbeite ...!
David Dury

2
"funktioniert nicht" bietet keine sehr gute Beschreibung dessen, was nicht funktioniert. Was ist die Fehlermeldung, die Sie erhalten?
John Koerner

@ JohnKoerner Ich denke, es ist ziemlich offensichtlich, dass der Compiler Ihnen den gleichen Fehler gibt, als ob Sie versucht hätten, einen Wert in einer voidFunktion zurückzugeben.
Binki

Antworten:


236

asyncMethoden unterscheiden sich von normalen Methoden. Was auch immer Sie von asyncMethoden zurückgeben, sind in a eingeschlossenTask .

Wenn Sie keinen Wert (void) zurückgeben, wird er eingewickelt Task. Wenn Sie intihn zurückgeben, wird er eingewickelt Task<int>und so weiter.

Wenn Ihre asynchrone Methode zurückgegeben werden muss, intmarkieren Sie den Rückgabetyp der Methode als Task<int>und geben einfach intnicht den zurück Task<int>. Compiler wird die konvertieren intzu Task<int>für Sie.

private async Task<int> MethodName()
{
    await SomethingAsync();
    return 42;//Note we return int not Task<int> and that compiles
}

Sameway, Wenn Sie zurückgeben, sollte der Rückgabetyp Task<object>Ihrer Methode seinTask<Task<object>>

public async Task<Task<object>> MethodName()
{
     return Task.FromResult<object>(null);//This will compile
}

Da Ihre Methode zurückgibt Task, sollte sie keinen Wert zurückgeben. Andernfalls wird es nicht kompiliert.

public async Task MethodName()
{
     return;//This should work but return is redundant and also method is useless.
}

Beachten Sie, dass eine asynchrone Methode ohne awaitAnweisung dies nicht ist async.


1
Für mich funktioniert dieser Rückgabetyp nicht (ich glaube, ich mache etwas falsch). Beispiel für eine statische asynchrone Aufgabe <string> DoStuff () {... = warte auf SomeMethodAsync (); return "string value"; } .. var x = DoStuff (); Aber dieses x - ist vom Typ "Task <string>", nicht vom Typ "string" ... Warum ist das so?
Prokurors

3
@Prokurors Sie müssen auch warten DoStuff(). Zum Beispiel:var x = await DoStuff();
Sriram Sakthivel

5
Sollte seinreturn await Task.FromResult<object>(null);
Sandeep Talabathula

@sandeeptalabathula, die gleich null
zurückgibt

2
@ProfK Task.WhenAnyist ein Beispiel.
Servy

55

Sie müssen das Schlüsselwort await verwenden, wenn Sie asynchron verwenden, und Ihr Funktionsrückgabetyp sollte generisch sein. Hier ein Beispiel mit einem Rückgabewert:

public async Task<object> MethodName()
{
    return await Task.FromResult<object>(null);
}

Hier ist ein Beispiel ohne Rückgabewert:

public async Task MethodName()
{
    await Task.CompletedTask;
}

Lese das:

TPL: http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx und Aufgaben: http://msdn.microsoft.com/en-us/library/system.threading .tasks (v = vs.110) .aspx

Async: http://msdn.microsoft.com/en-us/library/hh156513.aspx Warten Sie: http://msdn.microsoft.com/en-us/library/hh156528.aspx


9
Sie können einfach nulldirekt zurückkehren, anstatt auf eine Dummy-Aufgabe zu warten.
Lee

5
@Lee, aber wenn Sie das tun, beschwert sich der Compiler (gibt eine Warnung), dass die asyncMethode asynchron ausgeführt wird, mit dem Vorschlag, das awaitSchlüsselwort irgendwo in der Methode zu verwenden. Ich schlage vor, nur return Task.FromResult((object)null);das asyncSchlüsselwort zu verwenden und zu entfernen , um das Compiler-Warngeräusch zu reduzieren.
Binki

Ja, ich habe versucht, nur returnin einer Aufgabe zu verwenden, aber die Aufgabe wird weiterhin ausgeführt, da returnkeinTask
Turner Bass

30

Das Hinzufügen des asynchronen Schlüsselworts ist nur syntaktischer Zucker, um die Erstellung einer Zustandsmaschine zu vereinfachen. Im Wesentlichen nimmt der Compiler Ihren Code;

public async Task MethodName()
{
     return null;
}

Und verwandelt es in;

public Task MethodName()
{
     return Task.FromResult<object>(null);
}

Wenn Ihr Code awaitSchlüsselwörter enthält, muss der Compiler Ihre Methode in eine Klasse umwandeln , um die für die Ausführung erforderliche Zustandsmaschine darzustellen. Bei jedemawait Schlüsselwort bleiben der Status der Variablen und der Stapel in den Feldern der Klasse erhalten. Die Klasse fügt sich selbst als Abschluss-Hook zu der Aufgabe hinzu, auf die Sie warten, und kehrt dann zurück.

Wenn diese Aufgabe abgeschlossen ist, wird Ihre Aufgabe erneut ausgeführt. Daher wird oben in der Methode etwas zusätzlicher Code hinzugefügt, um den Status der Variablen wiederherzustellen und in die nächste Platte Ihres Codes zu springen.

Siehe Was generiert async & await?für ein blutiges Beispiel.

Dieser Prozess hat viel mit der Art und Weise zu tun, wie der Compiler mit Iteratormethoden mit Yield-Anweisungen umgeht.


2

Dies ist eine Aufgabe, die eine Aufgabe vom Typ String zurückgibt (anonyme C # -Funktion oder mit anderen Worten, eine Delegation wird 'Func' verwendet).

    public static async Task<string> MyTask()
    {
        //C# anonymous AsyncTask
        return await Task.FromResult<string>(((Func<string>)(() =>
        {
            // your code here
            return  "string result here";

        }))());
    }

1
Wenn Sie den Code als Antwort veröffentlichen, geben Sie bitte eine Erklärung an, was Sie demonstrieren. In diesem Fall fügen Sie eine Antwort auf eine alte Frage hinzu, die bereits mehrere Antworten enthält. Bitte fügen Sie ein oder zwei Sätze hinzu, die beschreiben, was Ihre neue Antwort zeigt, die in den anderen Antworten noch nicht gezeigt wurden. Ich sage nicht, dass etwas mit Ihrer Antwort nicht stimmt, sondern dass Sie anderen helfen, indem Sie in Worte fassen, was Sie mit Ihrem Code zeigen.
ToolmakerSteve

0

Um die richtigen Antworten von asynchronen Methoden zu erhalten, müssen Sie beim Aufrufen dieser Task-Methoden warten. Das wartet darauf, dass es wieder in den zurückgegebenen Werttyp und nicht in den Aufgabentyp konvertiert wird.

ZB var content = warte auf StringAsyncTask (

where public async Task < String > StringAsyncTask ())

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.