Da ich es nicht geschrieben habe kann ich nicht sicher wissen. ;) Aber ich denke, es ist in Bezug auf die return await
-anti-Muster.
Es gibt sogar ein Problem auf GitHub, wo die Anfrage ist, dass Roslyn es beim Kompilieren behandelt.
Optimize an async method that ends "return await e" to be non-async "return e"
diese Optimierung würde die Leistung einer Asynchron-Methode erwarten, deren Verbesserung erst am Ende erscheint. Nicht bei der Erstellung von Debug-Code und nicht bei Verschachtelung in einem try-Block.
den ausgezeichneten Kommentar von damien_the_unbeliever zu zitieren, die er auf this question geschrieben
await
ist eine Möglichkeit, die aktuelle Methode der Pause, bis ein anderes Stück Code seine Arbeit geleistet hat. Wenn alles, was Ihre Methode tun wird, wenn es wieder aufgenommen wird, ist zu sagen, "Ich bin fertig", dann warum gehen Sie zu allen Aufwand? Davon abgesehen, ist das tatsächliche anti-Muster ist return await
wenn dass die nurawait
bei dem Verfahren ist (wie hier), und es ist nicht innerhalb eines try
Blockes mit einem finally
oder einem using
Block (in diesem Fall bestehen Zusatzcode nach der Rückkehr
laufen Bei der Verwendung von await/async
sollte man es schafft der Ober bewusst sein
diese beiden Klassen Nehmen sie zum Beispiel:.
public class BaseClass
{
public async Task<int> GetIdAsync()
{
return await Task.Run(() => 100);
}
}
public class Foo : BaseClass
{
public Task<int> GetId()
{
return GetIdAsync();
}
}
public class Bar : BaseClass
{
public async Task<int> GetId()
{
return await GetIdAsync();
}
}
Wenn Sie den Code aus Bar
mit ILSpy decompile etwas wie folgt aussehen:
public class Bar : BaseClass
{
[DebuggerStepThrough, AsyncStateMachine(typeof(Bar.<GetId>d__0))]
public Task<int> GetId()
{
Bar.<GetId>d__0 <GetId>d__ = new Bar.<GetId>d__0();
<GetId>d__.<>4__this = this;
<GetId>d__.<>t__builder = AsyncTaskMethodBuilder<int>.Create();
<GetId>d__.<>1__state = -1;
AsyncTaskMethodBuilder<int> <>t__builder = <GetId>d__.<>t__builder;
<>t__builder.Start<Bar.<GetId>d__0>(ref <GetId>d__);
return <GetId>d__.<>t__builder.Task;
}
}
Während Foo
wie folgt aussieht:
public class Foo : BaseClass
{
public Task<int> GetId()
{
return base.GetIdAsync();
}
}
Also, um es zusammenzufassen, wenn Sie einfach, um den Wert von einem Task
zurückzugeben, gibt es wirklich keinen Grund zu await
es. Stattdessen sollten Sie den Task
zurückgeben und den Anruferawait
stattdessen Task
zurückgeben lassen.Das Erweitern der Task
erweitert den Stapel und erstellt einen Overhead, der die Leistung nur negativ beeinflusst.
Und was ist mit Ausnahmeausbreitung. Async/await stellt die Fortsetzung sicher und ermöglicht, dass die Ausnahme korrekt zurückgegeben wird. Wäre es ein Problem, wenn ich nur Aufgabe und eine Ausnahme geworfen wird? Ich habe versucht, eine schnelle Antwort zu finden, wenn async/await den ersten Thread überspringen und mit einem anderen fortfahren kann, aber ich habe das noch nicht geklärt. – BeStelios
Der GitHub-Link behandelt die Behandlung von Ausnahmen. Das Zurückgeben der Aufgabe würde tatsächlich den Stapel für die Ausnahme ändern. Die "Task" muss noch abgewartet werden, daher sollte die Ausnahme immer noch zurückgegeben werden, aber wahrscheinlich in einem anderen Stack. – smoksnes