2017-12-11 7 views
0

Ich stieß auf den folgenden Code, der die ContinueWith() verwendet, um auf das Ergebnis warten.Verwenden ContinueWith() für eine erwartete Aufgabe und Aufruf von Task.Result innerhalb

public async Task<User> GetUser() 
{ 
    return await _serviceRepo.GetUserAsync() 
     .ContinueWith(task => 
     { 
      return task.Result; 
     }); 
} 

blockiert die ContinueWith() den aufrufenden Thread, bis Aufgabe kehrt von der GetUserAsync() Anruf?

Da die task.Result innerhalb der ContinueWith() ist, die geplant ist, wird alles während des Wartens auf den Vorgänger task blockiert?

Ich habe diese Art von Code in einigen anderen Orten gesehen, ist dies eine Best Practice für die async/erwarten Muster? Ich würde erwarten, dass der GetUserAsync() Anruf das Ergebnis zurückgibt, als mit einem ContinueWith() darauf zu warten.

+2

Sie verwenden 'ContinueWith' nicht bei der erwarteten' Task'. Sie warten auf die Fortsetzung 'Aufgabe', die mit' ContinueWith' erstellt wurde. BTW, warum nicht verwenden Sie öffentliche Aufgabe GetUser() => _serviceRepo.GetUserAsync(); ' – PetSerAl

+0

Es gibt keinen Grund, es so zu tun. Sie können async, await und ContinueWith vollständig entfernen. – Evk

Antwort

1

Blockiert der ContinueWith() den aufrufenden Thread, bis die Task vom GetUserAsync() Aufruf zurückkehrt?

Nein, der Thread wird nicht blockiert, da dies eine async Operation ist. Seien Sie sich jedoch bewusst, dass der angegebene Code nicht auf die Aufgabe wartet, sondern die Fortsetzung, die Sie während des Debuggens in die Irre führen kann.

Da die task.Result innerhalb des ContinueWith() ist, die geplant ist, wird alles blockiert wird, während für die vorhergehende Aufgabe warten?

Nein, die Aufgabe ist bereits beendet und der aktuelle Thread wird nicht blockiert. Die Ausnahme wird jedoch ausgelöst, wenn die Aufgabe nicht erfolgreich abgeschlossen wurde.

Wird dies als Best Practice für das asyn/awarn-Muster angesehen?

Nein, dieser Code kann in Form umgeschrieben werden:

public async Task<User> GetUser() 
{ 
    return await _serviceRepo.GetUserAsync(); 
} 

Allerdings, wenn es eine gewisse Logik in Fortsetzung ist, wie folgt aus:

public async Task<User> GetUser() 
{ 
    return await _serviceRepo.GetUserAsync() 
     .ContinueWith(task => 
     { 
      // do something with the result, for example, log the success 

      return task.Result; 
     }); 

Sie dies tun können:

public async Task<User> GetUser() 
{ 
    var user = await _serviceRepo.GetUserAsync(); 

    // do something with the result, for example, log the success 

    return user; 
} 
+0

Gründe für das Downvote? – VMAtm

Verwandte Themen