Folgendes meine ich:
public Task<SomeObject> GetSomeObjectByTokenAsync(int id)
{
string token = repository.GetTokenById(id);
if (string.IsNullOrEmpty(token))
{
return Task.FromResult(new SomeObject()
{
IsAuthorized = false
});
}
else
{
return repository.GetSomeObjectByTokenAsync(token).ContinueWith(t =>
{
t.Result.IsAuthorized = true;
return t.Result;
});
}
}
Die obige Methode kann abgewartet werden, und ich denke, sie ähnelt stark dem, was das T- Ask-basierte A- Synchron- P- Muster vorschlägt. (Die anderen mir bekannten Muster sind die APM- und EAP- Muster.)
Was ist nun mit dem folgenden Code:
public async Task<SomeObject> GetSomeObjectByToken(int id)
{
string token = repository.GetTokenById(id);
if (string.IsNullOrEmpty(token))
{
return new SomeObject()
{
IsAuthorized = false
};
}
else
{
SomeObject result = await repository.GetSomeObjectByTokenAsync(token);
result.IsAuthorized = true;
return result;
}
}
Die Hauptunterschiede hierbei sind, dass die Methode async
die await
Schlüsselwörter verwendet und verwendet. Was ändert sich also im Gegensatz zur zuvor geschriebenen Methode? Ich weiß, dass es auch erwartet werden kann. Jede Methode, die Task zurückgibt, kann dies tun, es sei denn, ich irre mich.
Ich bin mir der Zustandsmaschine bewusst, die mit diesen switch-Anweisungen erstellt wurde, wenn eine Methode als gekennzeichnet ist async
, und ich bin mir bewusst, dass sie await
selbst keinen Thread verwendet - sie blockiert überhaupt nicht, der Thread erledigt einfach andere Dinge, bis dies der Fall ist zurückgerufen, um die Ausführung des obigen Codes fortzusetzen.
Aber was ist der zugrunde liegende Unterschied zwischen den beiden Methoden, wenn wir sie mit dem await
Schlüsselwort aufrufen ? Gibt es überhaupt einen Unterschied, und wenn ja, welcher wird bevorzugt?
BEARBEITEN: Ich bin der Meinung, dass das erste Code-Snippet bevorzugt wird, da wir die Schlüsselwörter async / await effektiv eliminieren , ohne dass dies Auswirkungen hat. Wir geben eine Aufgabe zurück, die ihre Ausführung synchron fortsetzt, oder eine bereits abgeschlossene Aufgabe auf dem Hot Path (was sein kann) zwischengespeichert).
result.IsAuthorized = true
wird es im Thread-Pool ausgeführt, während es im zweiten Beispiel möglicherweise im selben Thread ausgeführt wird, der aufgerufen wurdeGetSomeObjectByToken
(wenn ein Thread daraufSynchronizationContext
installiert war, z. B. ein UI-Thread). Das Verhalten beimGetSomeObjectByTokenAsync
Auslösen einer Ausnahme unterscheidet sich ebenfalls geringfügig. Im Allgemeinenawait
wird es vorgezogenContinueWith
, da es fast immer besser lesbar ist.