2016-09-21 1 views
4

Ich bin ein C# -Newbie, so habe ich Probleme, einige Konzepte zu verstehen, und ich laufe in ein Stück Code, den ich ' m nicht ganz verstehn:Verständnis der Verwendung von Task.Run + Wait() + async + erwarten in einer Zeile verwendet

static void Main(string[] args) 
{ 
Task.Run(async() => { await SomeClass.Initiate(new Configuration()); }).Wait(); 
while (true) ; 
} 

Wie ich verstehe, führt dies eine Aufgabe, die eine Methode initiiert. Diese Methode wird ausgeführt und nachdem sie beendet wurde, wird sie in eine Endlosschleife versetzt. Es fühlt sich an, dass entweder der Code keinen Sinn ergibt, oder dass ich nicht richtig verstehe.

Dank

+0

Es wird ein asynchrones Verfahren 'SomeClass.Initiate' zwingt synchron ausgeführt werden. Die Task.Run, die die Async-Methode umschließt, wird nicht benötigt. Die Endlosschleife soll verhindern, dass das Konsolenfenster unmittelbar nach Abschluss von "Initiieren" geschlossen wird. Woher kam dieser Code, gibt es einen Zusammenhang dafür? – ndonohoe

+0

Es gibt bessere Code-Stücke, die für das Ausführen von asynchronen Methoden in der Konsolen-App "run-in" sind - http://StackOverflow.com/questions/17630506/async-at-console-app-in-c –

Antwort

7

Sie können diese auseinander brechen in mehrere Teile:

async() => { await SomeClass.Initiate(new Configuration()); } 

Ist ein Lambda-Ausdruck, der eine async Methode definiert, die nur eine andere Methode erwartet. Dieses Lambda wird dann an Task.Run:

Task.Run(async() => { await SomeClass.Initiate(new Configuration()); }) 

Task.Run führt seinen Code auf einem Threadpool-Thread. Also, dass async Lambda wird auf einem Thread-Pool-Thread ausgeführt werden. Task.Run gibt eine Task zurück, die die Ausführung des async Lambda darstellt. Nach Task.Run Aufruf ruft der Code Task.Wait:

Task.Run(async() => { await SomeClass.Initiate(new Configuration()); }).Wait(); 

Dies wird die Hauptkonsole App blockiert, bis das Asynchron-Lambda vollständig beendet ist.

Wenn Sie sehen wollen, wie es weiter ausgebrochen ist, ist die folgende entspricht in etwa:

static async Task AnonymousMethodAsync() 
{ 
    await SomeClass.Initiate(new Configuration()); 
} 

static void Main(string[] args) 
{ 
    var task = Task.Run(() => AnonymousMethodAsync()); 
    task.Wait(); 
    while (true) ; 
} 
+0

was ist der Zweck von ' während (wahr) aber am Ende? –

+0

@information_interchange: Es war im ursprünglichen Code des op. –

1

Wahrscheinlich SomeClass.Initiate ist synchrone Methode async ohne Grund gekennzeichnet. Als jemand versucht hat, es wirklich asynchron laufen zu lassen und fügte Task.Run hinzu, um es auf separatem Thread zu laufen. Aber da es sich um eine Konsolenanwendung handelt, wurde .Wait() hinzugefügt, um auf den Abschluss des Vorgangs zu warten.

Und while (true) ; ist da, wenn beim Ausführen in VS Konsole App schließt ohne Rückverfolgung, wenn es fertig ist, offensichtlicher Weg - Console.ReadLine() Anruf hinzufügen. while(true) ist überhaupt nicht async Teil als Code wird nicht verlassen .Wait() Anruf vor der Operation ausgeführt wird.

Ein andere Möglichkeit ist Autor mit async experimentiert und hat nicht .Wait() oder .Result - so while(true) Chance geben würde, für den Betrieb zu beenden.

Siehe async at console app in C#? für die richtige Art und Weise Asynchron-Code in Konsolenanwendung (nur .Wait() oder .Result)

2

Ich schrieb ein kleines .NET Fiddle, die einfach hinzugefügt einige Console.WriteLine Anrufe hoffentlich zu helfen, zeigen Ihnen die Reihenfolge der Ausführung zu laufen. Die Task.Run gibt eine Task zurück, die eine asynchrone Operation darstellt (eine Methode, die asynchron ausgeführt wird). In dieser Situation ist der Parameter Func<Task>. Ihr Code hat die Schlüsselwörter async und await verwendet, daher ist Ihr Anruf an SomeClass.Initiate ein asynchrones Lambda.

Stellt die angegebene Arbeit in den Thread-Pool ein und gibt einen Proxy für die von der Funktion zurückgegebene Aufgabe zurück.

Alle Asynchron-Code sollte eine awaitable zurückkehren, es sei denn, in der seltenen Situation, wo Sie einen Event-Handler sind Authoring, die einige async Anrufe starten muss.

The Task, die sofort aus dem Aufruf von Task.Run zurückgegeben wird .Wait() aufruft.

Wartet darauf, dass der Task die Ausführung innerhalb eines angegebenen Zeitintervalls abschließt.

, die auf Task.Run nennen ist nicht erforderlich, Sie einfach .Wait() auf den Task berufen könnte, die von der SomeClass.Initiate Methode zurückgegeben wird.

Wie für die Endlos-Schleife, eine Konsolenanwendung verlässt sofort - Sie einfach die Console.ReadLine tun könnte und für den Benutzer warten, bis die Geben Sie Schlüssel zum Beispiel zu schlagen.

Verwandte Themen