2016-12-01 1 views
1

Tutorials manchmal diesen Code Implementierung eigener Asynchron-Methoden wie zum Beispiel zeigen:Muss ASync Methoden von OS unterstützt werden oder Asynchron-Programmebene Feature

async public static Task GetHttpResponseAsync() 
{ 
    using (HttpClient httpClient = new HttpClient()) 
    { 
     HttpResponseMessage response = await httpClient.GetAsync(...); 
     Console.WriteLine(response.Something); 
    }    
} 

, was mir klar ist, ist wie async Arbeit im Allgemeinen, aber keiner von Tutorials erklärt, wie intern umgesetzt werden

httpClient.GetAsync(...); 

, die wirklich wichtig ist zu verstehen, wie asynchoronus Code funktioniert in Details. Was macht mich neugierig, wenn interne Operationen von GetAsync (diese Methode oder andere asynchrone Methode) in einer Art Container registriert sind, in dem dieser Code ausgeführt wird? Müssen asynchrone Methoden vom Betriebssystem unterstützt werden (z. B. Windows API)? Wenn ich meinen eigenen asynchronen Datei-Downloader (vom Datenträger und ohne wesentlichen Teil von .NET Framework) implementieren möchte, wie würde ich es implementieren, sollte ich meine Methode irgendwo für den weiteren Aufruf registrieren?

Es ist ziemlich klar für mich, dass intern Compiler macht State Machine und nach DoSomething() -Methode tun, was es zu haben, rufen Sie nur diese Zustandsmaschine wieder auf den Code nach dem Ausführen wieder auszuführen.

Auch was für mich unklar ist, dass async-Code auf demselben Thread ausgeführt werden kann. Ich denke, dass das Aufrechterhalten der Zustandsmaschine auf demselben Thread sein muss, aber wie der Code von httpClient.GetAsync() auf demselben Thread ausgeführt werden kann und andere Operationen (z. B. GUI) nicht unterbricht. Es muss etwas geben, das diesen Code in einem separaten Thread ausführen lässt (in allen Fällen). Liege ich falsch? Was ich vermisst habe?

Zusätzliche Erklärung meiner Frage: In JavaScript, so weit ich weiß und zu verstehen, arbeitet async Methoden, indem sie sie in einer Art von Container registrieren (die sie nacheinander auf separaten Thread ausführt), die diese Methode ausführt. Nachdem die Ausführung der Methode abgeschlossen ist, wird das Ergebnis an den Benutzerkontext zurückgegeben. Für mich ist klar, ob das hier genauso funktioniert?

+0

'async/await 'ist eine Funktion auf Programmebene, die das Schreiben von Code für die Verknüpfung mit erwarteten Objekten ergonomischer gestaltet. Asynchronität selbst ist jedoch eine Eigenschaft Ihrer Schnittstelle zu irgendwelchen Entitäten, mit denen Ihr Programm kommuniziert. Eine synchrone Schnittstelle lässt Sie auf die von Ihnen gewünschte Antwort warten, während eine asynchrone Schnittstelle Ihre Anfrage annimmt und einen Mechanismus bereitstellt, mit dem Sie zurückgerufen werden können, wenn Sie bereit sind. Asynchrone Schnittstellen übersetzen gut zu erwarteten Objekten, während synchrone Schnittstellen dies nicht tun. –

+0

@AsadSaeeduddin Also, es muss etwas, das Code auf separaten Thread ausgeführt wird und danach zwingen, Benutzer-Thread (zB ui thread) diese asynchronen Methoden noch einmal zu State Machine wechseln und verbleibenden Code ausführen? – Puchacz

+0

Nun, mit einer HTTP-Anfrage wäre der "separate Thread" möglicherweise Millionen von Meilen entfernt ein Server. Ihr Programm würde keinen Rechenaufwand (nicht einmal in einem anderen Thread) aufwenden und wäre frei, andere Dinge wie die Reaktion auf Benutzereingaben zu tun. In Bezug auf "force user thread" ist no: async/awaward nicht präventiv. Async/await kann vollständig implementiert werden, ohne auf irgendwelche verfügbaren Threads angewiesen zu sein. Es ist nur ein Transformationsmechanismus, mit dem Sie Methoden in Schritte aufteilen und Fortsetzung fortsetzen können, ohne darüber nachzudenken. –

Antwort

2

Kurz gesagt, muss echte Asynchronität auf Betriebssystemebene bereitgestellt werden. Wie Sie bereits festgestellt haben, ist async/await ein Feature auf Sprachenebene, das Compiler-generierte Statusmaschinen verwendet, um Ihre Methode in Teile zu zerlegen, die asynchron ausgeführt werden können. Sie basiert jedoch auf Betriebssystemprimitiven (Interrupts, Threads), um diese Arbeit auszuführen in einer asynchronen Weise.

Allerdings ist es wichtig zu beachten, dass es oft nicht sein wird ein Thread erstellt, um Ihre asynchrone Operation zu behandeln. Ich werde auf diesen fachkundig geschriebenen Artikel verweisen, um zu beschreiben, warum dies der Fall ist: http://blog.stephencleary.com/2013/11/there-is-no-thread.html

Unter Windows ist der primäre Mechanismus für die Durchführung asynchroner Arbeit mit I/O Completion Ports. Dies ist eine Windows-API, die von vielen .NET-Typen verwendet wird, einschließlich der HttpClient, die Sie verwenden.

Beachten Sie, dass Sie für Non-I/O-Vorgänge auch immer Threads oder besser noch Thread Pool API verwenden können, um Hintergrundarbeiten durchzuführen, die asynchron abgeschlossen werden.

Die ReadFile (oder neuere ReadFileEx) -Funktion in der Windows-API wurde entwickelt, um mit asynchronen E/A zu arbeiten. Wenn Sie ReadFile aufrufen, können Sie das Flag FILE_FLAG_OVERLAPPED verwenden und eine OVERLAPPED-Struktur an das Argument lpOverlapped übergeben, das Async-Lesevorgänge aktiviert. Ich möchte Sie ermutigen, diese API zu verwenden, um Ihren Datei-Downloader zu entwerfen.


Zusammengefasst:

Verwandte Themen