Was ist der Hauptunterschied zwischen der Rückgabe einer Aufgabe durch das await-Schlüsselwort und der Rückgabe ohne await-Schlüsselwort?

8

Ich verpacke AspNet.Identity. Aber etwas verwirrt mich über TPL.

Erstes Beispiel:

%Vor%

Zweites Beispiel:

%Vor%

Und der Kunde wird dies wie folgt nennen:

%Vor%

Meine erste Frage ist:

Wenn der Client die zweite Methode aufruft, wird die Arbeit aus dem IO-Thread in einen Threadpool-Thread ausgelagert. Und wenn RemovePasswordAsync aufgerufen wird, ruft es UpdateAsync auf, das ein Warte-Schlüsselwort hat. An diesem Punkt wird dieser Threadpool-Thread in einen anderen Threadpool-Thread ausgelagert. Oder verwendet TPL stattdessen den gleichen Thread?

Und meine zweite Frage ist; Was ist der Hauptunterschied zwischen der ersten Implementierung und der zweiten Implementierung der Konstruktion dieser asynchronen Methode?

BEARBEITEN:

Dies ist die Aktualisierungsmethode der UserStore-Klasse. (_store.UpdateAsync (Benutzer))

%Vor%

Und das ist die Update-Methode der UserService-Klasse

%Vor%     
Kemal Gültekin 25.02.2014, 13:06
quelle

2 Antworten

3

Ich beantworte Ihre erste Frage.

Sie missverstehen, wie async / wait funktioniert.

Eine async -Methode wird synchron mindestens ausgeführt, bis sie die erste await -Anweisung erreicht. Wenn es auf await trifft, hat es zwei Optionen:

  • Wenn das erwartete (z. B. Task ) bereits abgeschlossen ist, wird der aktuelle Kontext (d. h. UI-Thread oder der Kontext der ASP.NET-Anfrage) ausgeführt.
  • Wenn das Erwartete noch nicht abgeschlossen ist, wird der übrige Text der Methode umgebrochen und geplant, dass der aktuelle Kontext (z. B. UI-Thread) (*) ausgeführt wird, wenn die Aufgabe abgeschlossen ist.

Nach dieser Definition wird der gesamte Code im Kontext der gleichen ASP.NET-Anfrage ausgeführt.

_store.UpdateAsync kann jedoch einen ThreadPool-Thread generieren (z. B. mithilfe von Task.Run ).

Aktualisiert

Gemäß Ihrer aktualisierten Antwort wird Update(user) in einem ThreadPool-Thread ausgeführt. Alles andere wird im aktuellen Kontext ausgeführt.

(*) Der Rest des Hauptteils der Methode wird so geplant, dass er in einem ThreadPool-Thread ausgeführt wird wenn kein Synchronisierungskontext (d. h. Konsolenanwendung) vorhanden ist.

    
dcastro 25.02.2014, 13:20
quelle
2
  

Und meine zweite Frage ist; Was ist der Hauptunterschied zwischen den?   erste Implementierung und die zweite Implementierung des Konstruierens   diese asynchrone Methode?

Ihre erste Implementierung kann und sollte verbessert werden, indem Sie das blockierende _store.FindByIdAsync(userId).Result durch das asynchrone await _store.FindByIdAsync(userId) ersetzen:

%Vor%

Ohne eine solche Aktualisierung wird der Unterschied vielleicht am besten von Eric Lippert hier beschrieben. Eine besondere Sache ist , wie Ausnahmen möglicherweise ausgelöst werden und behandelt werden.

Aktualisiert, um die Kommentare zu bearbeiten . Sie sollten nicht mit Task.Factory.StartNew oder Task.Run in ASP.NET verschieben. Dies ist nicht eine UI-App, in der Sie die Benutzeroberfläche ansprechend halten müssen. All dies fügt nur einen Overhead eines Thread-Schalters hinzu. Der HTTP-Request-Handler, der Task.Run aufruft, dann erwartet oder blockiert, benötigt mindestens die gleiche Anzahl von Threads, um sie zu vervollständigen. Sie werden die Skalierbarkeit nicht verbessern und nur die Performance beeinträchtigen. Auf der anderen Seite macht es Sinn, natürlich IO-gebundene Aufgaben zu verwenden, die keinen Thread während der Ausführung verwenden.

    
Noseratio 25.02.2014 13:44
quelle