it-swarm.com.de

Wie wird Task <int> zu einem int?

Wir haben diese Methode:

async Task<int> AccessTheWebAsync()
{ 
    HttpClient client = new HttpClient();

   Task<string> getStringTask = client.GetStringAsync("http://msdn.Microsoft.com");

   // You can do work here that doesn't rely on the string from GetStringAsync.
   DoIndependentWork();

   string urlContents = await getStringTask;
   //The thing is that this returns an int to a method that has a return type of Task<int>
   return urlContents.Length;
}

Tritt eine implizite Konvertierung zwischen Task<int> und int? Wenn nicht, was passiert dann? Wie ist es implementiert, um zu arbeiten?

98
Freeman

Findet eine implizite Konvertierung zwischen Task <> und int statt?

Nee. Dies ist nur ein Teil der Funktionsweise von async/await.

Jede als async deklarierte Methode muss den folgenden Rückgabetyp haben:

  • void (möglichst vermeiden)
  • Task (kein Ergebnis nach Benachrichtigung über Fertigstellung/Fehler)
  • Task<T> (Für ein logisches Ergebnis vom Typ T auf asynchrone Weise)

Der Compiler nimmt alle erforderlichen Änderungen vor. Der Punkt ist, dass Sie asynchronurlContents.Length Zurückgeben - Sie können die Methode nicht einfach dazu bringen, int zurückzugeben, da die tatsächliche Methode zurückgibt, wenn sie die erste trifft await Ausdruck, der noch nicht abgeschlossen ist. Stattdessen wird ein Task<int> Zurückgegeben, der abgeschlossen wird, wenn die asynchrone Methode selbst abgeschlossen ist.

Beachten Sie, dass await das Gegenteil bewirkt - es entpackt einen Task<T> Zu einem T Wert, wie diese Zeile funktioniert:

string urlContents = await getStringTask;

... aber natürlich entpackt es es asynchron, während nur die Verwendung von Result blockieren würde, bis die Aufgabe abgeschlossen war. (await kann andere Typen auspacken, die das erwartete Muster implementieren, aber Task<T> ist der Typ, den Sie wahrscheinlich am häufigsten verwenden.)

Diese doppelte Umhüllung/Enthüllung ermöglicht es, dass Async so zusammensetzbar ist. Zum Beispiel könnte ich eine andere asynchrone Methode schreiben, die deine aufruft und das Ergebnis verdoppelt:

public async Task<int> AccessTheWebAndDoubleAsync()
{
    var task = AccessTheWebAsync();
    int result = await task;
    return result * 2;
}

(Oder einfach return await AccessTheWebAsync() * 2; natürlich.)

146
Jon Skeet

Nein erfordert die Konvertierung der Task in int. Verwenden Sie einfach das Aufgabenergebnis.

int taskResult = AccessTheWebAndDouble().Result;

public async Task<int> AccessTheWebAndDouble()
{
    int task = AccessTheWeb();
    return task;
}

Wenn verfügbar, wird der Wert zurückgegeben, andernfalls wird 0 zurückgegeben.

11
Aniket Sharma