2016-12-22 7 views
1

Ich habe den folgenden Code aufgerufen Methoden anwenden:Hat async await auch

public async Task<IHttpActionResult> GetInfo(string text) 
    { 
     var res = await Class.ClassMethod(text); 

     if (res == null) 
     { 
      return BadRequest("Fail"); 
     } 
     return Ok(res); 
    } 

und dieses ist ClassMethod:

public async static Task<string> ClassMethod(string text) 
    { 
     NextClass followingClass = new NextClass(); 
     return followingClass.followingClassMethod(text); 
    } 

Meine Frage bezieht sich in der ClassMethod Async.

In dieser Situation wird Class.ClassMethod(text) mit await aufgerufen, die, soweit ich verstehe, bedeutet, dass die Methode nicht mehr async sein wird, aber in der Reihenfolge ausgeführt wird. Alles soweit in Ordnung.

Aber wird die await Funktion Methoden in der Class Funktion aufgerufen gelten, nach await zB umgesetzt wurde, wird der Code in followingClassMethod auch await angewendet haben, oder will ich brauche auch await zu followingClassmethod hinzuzufügen.

Wenn warten auf followingClassMethod gelten wird, gilt es auch für alle Methoden, die in followingClassMethod und so weiter aufgerufen werden. Wenn ja, wann wird es aufhören zu bewerben?

Wenn dies nicht zutrifft, bedeutet das, dass in ClassMethod der Konstruktor und die Methode beide gleichzeitig ausgeführt werden? Was offensichtlich nicht funktioniert. Wenn dies der Fall ist, was kann ich tun, um dies zu beheben, da ich einen Konstruktor nicht mit Async aufrufen kann? Ich habe einige Antworten gesehen, die sagen, den Konstruktor in eine Methode zu packen und async zu machen, aber das scheint mir etwas hacky zu sein?

Antwort

1

aufgerufen mit erwarten, die, soweit ich verstehe, bedeutet die Methode wird nicht mehr async sein, wird aber in der Reihenfolge ausgeführt werden.

Nein, das ist nicht was es bedeutet; es bedeutet, dass alles auf der linken Seite und darunter (var res = usw.) Teil der Folge ist, und wird nur ausgeführt, sobald die erwartete Sache (das Ergebnis von Class.ClassMethod(text)) zeigt Abschluss.

Allerdings müssen wir auch wissen, was followingClassMethod zurückgibt. Es sieht so aus, als ob es string zurückgibt, in diesem Fall ist die async irrelevant, und diese Methode führt immer synchron aus und gibt einfach eine bereits abgeschlossene Aufgabe zurück; was bedeutet, dass die var res = Folge auch sofort/synchron ausführt. Als Nebenwirkung Sie wahrscheinlich bereits eine Compiler-Warnung erhalten:

Warnung CS1998 Diese async Methode synchron ‚erwarten‘ Operatoren und läuft fehlt. Ziehen Sie in Erwägung, den Operator 'abwarten' zu verwenden, um nicht blockierende API-Aufrufe abzuwarten, oder 'warten Sie auf Task.Run (...)', um CPU-gebundene Arbeit an einem Hintergrund-Thread auszuführen.

was sagt Ihnen, dass die async nichts nützliches tut.

Was:

oder muss ich auch erwarten zu followingClassmethod hinzuzufügen.

Sie können nicht tun, es sei denn, das Ergebnis followingClassmethod selbst awaitable - zum Beispiel Task<string>; die naive Ansatz würde es dann schreiben sein:

public async static Task<string> ClassMethod(string text) 
{ 
    NextClass followingClass = new NextClass(); 
    return await followingClass.followingClassMethod(text); 
} 

aber dies eine unnötige Abstraktionsebene hinzufügt und gewinnt man nichts über einfach nicht async sein:

public static Task<string> ClassMethod(string text) 
{ 
    NextClass followingClass = new NextClass(); 
    return followingClass.followingClassMethod(text); 
} 
+0

Im obigen Fall kann ich sehen dass ClassMethod nicht asynchron sein muss. Wenn es jedoch notwendig war, dies als asynchrone Aufgabe zu haben, scheint es, dass Sie sagen, dass ich auch in ClassMethod erwarten müsste, ansonsten wäre es asynchron? – Alex

+1

@Alex, das davon abhängt, was Sie denken, dass Sie "wie async" meinen. Gibt es wirklich etwas, das wirklich asynchron ist? Es schreibt nicht 'async' /' wait', das etwas asynchron macht - das löst nur Compiler-Magie aus, um es zu ermöglichen, asynchronen Code zu schreiben, ohne so verrückt zu werden. Was Ihre letzte Frage angeht: Nein, und ich gab explizit ein Beispiel, in dem "ClassMethod" nicht "async" ist und dennoch die erwartete Natur von 'followingClassMethod' korrekt durchläuft (vorausgesetzt, dass * das * jetzt'async' ist) –

+1

@MarcGravell : Ich denke, dass 'async' /' wait' im 'ClassMethod' Code nützlich sein kann. Insbesondere, wenn der 'NextClass'-Konstruktor eine (nicht bone headed) Exception geworfen hat. –