2012-10-09 12 views
9

Mit den Vorteilen von async I/O und es jetzt sehr einfach zu codieren und zu komponieren (mit Await und die TAP-Methoden) frage ich mich, wenn wir standardmäßig async verwenden und nur nach Leistung durch Synchronisierung bei Bedarf optimieren.Sollen wir standardmäßig asynchrone E/A verwenden?

Async-E/A gibt den aufrufenden Thread frei und ermöglicht, etwas anderes zu tun, während auf das Ergebnis gewartet wird. Auf der anderen Seite ist async I/O etwas langsamer als Sync.

Um reaktionsschnelle UIs zu erzwingen, fanden die WinRT-Entwickler es akzeptabel, asynchrone Methoden anzubieten.

AFAIK Windows Datei E/A intern ist async. Wenn ich dies naiv betrachte, ist mir nicht klar, warum asynchrone Datei-E/A in .NET langsamer als überhaupt synchron sein sollte.

Ich bevorzuge in der Regel Einfachheit und Robustheit und nur bei Bedarf Leistung. In der Vergangenheit haben wir die Synchronisierung standardmäßig verwendet, mit der Ausnahme, dass einige Dienste aufgerufen wurden und Plattformen wie das Telefon async erzwingen. Wir haben selten mit Async abgestimmt.

+0

Der [pfxteam blog] (http://msdn.microsoft.com/en-us/magazine/jj133817.aspx) enthält einige interessante Informationen in diesem Zusammenhang: * "Bitte beachten Sie, dass wir keine asynchronen Versionen von hinzugefügt haben APIs mit sehr geringer Granularität, wie TextReader.Peek, weil asynchrone APIs zusätzlichen Overhead verursachen und wir verhindern wollten, dass Entwickler versehentlich in die falsche Richtung gehen, was bedeutet, dass wir uns ausdrücklich gegen asynchrone Versionen von Methoden entschieden haben auf BinaryReader oder BinaryWriter .... * –

Antwort

13

Die Verwendung von async IO ist mit C# 5 sehr einfach geworden, aber es sind immer noch Produktivitätskosten damit verbunden. Zum Beispiel müssen Sie neue Keywords, wo zuvor keine wo nötig, streuen. Sie müssen den Rückgabetyp Ihrer Methode ändern.

Wenn Sie später entscheiden, dass eine Methode IO ausführen soll, müssen Sie die gesamte Aufrufkette ändern, um zu async zu wechseln. Es ist eine nicht lokale Änderung, die sich auf andere Module ausbreitet.

Sie können Async-IO nicht profilieren. Profiling-Tools nehmen nichts auf. Wenn Sie den Debugger anhalten, befindet sich nichts auf einem der Thread-Stacks. Niemand scheint etwas zu tun. Das liegt daran, dass ein asynchrones IO keinen Thread enthält. Es ist nur eine Datenstruktur (ein Objekt im Kernel).

Die Entscheidung hängt auch vom Anwendungstyp ab. In einer WinForms- oder WPF-App würde ich lieber mit async arbeiten, da es sich so gut in den UI-Thread integriert.

In einer ASP.NET/WCF-Einstellung besteht der Hauptvorteil darin, dass Sie den Threadpool nicht ausschöpfen, während Sie lange laufende Back-End-Dienste aufrufen. Wenn Sie ein solches Problem nicht haben, und ich denke, das ist eher selten, Sie gewinnen sehr wenig von async IO. In der Tat verlieren Sie Leistung standardmäßig.

In einer Metro-Umgebung wurde die Entscheidung für Sie getroffen. Microsoft hat (legitim) entschieden, die Entwicklerproduktivität für die Benutzererfahrung zu tauschen.

So ist es keine klare Entscheidung. Die Vor- und Nachteile sind an dieser Stelle ziemlich schwach. Aus diesem Grund unterlasse ich eine eindeutige Empfehlung. Es kommt sehr auf den konkreten Fall an.

8

Ich würde empfehlen, async zu verwenden, wenn Sie eine natürlich-asynchrone Operation und sonst synchronen Code haben. Es ist wahr, dass async etwas langsamer ist, aber in den meisten Fällen ist es wie "das Radio in Ihrem Hummer aufdrehen" langsamer.

In UI-Programmen erhöht async die Reaktionszeit. In Server-Apps erhöht async die Skalierbarkeit.

AFAIK Windows Datei E/A intern ist async. Wenn ich dies naiv betrachte, ist mir nicht klar, warum asynchrone Datei-E/A in .NET langsamer als überhaupt synchron sein sollte.

Asynchroner Code ist langsamer, da er Strukturen zuweisen muss, um den asynchronen Vorgang zu verfolgen; Synchroner Code verwendet nur den aktuellen Thread (und seinen Stack). Daher ist die Operation selbst nicht langsamer, aber insgesamt gibt es eine leichte Geschwindigkeitsabnahme aufgrund von mehr Druck auf den Speicherbereiniger.

Ich bevorzuge in der Regel Einfachheit und Robustheit und nur bei Bedarf Leistung.

Ich stimme zu. Wenn Sie eine Operation haben, die natürlich asynchron ist (z. B. E/A), setzen Sie eine async API offen. Und wenn Sie eine Operation haben, die natürlich synchron ist, legen Sie eine synchrone API offen. Stephen Toub hat ein paar tolle Blog-Beiträge dazu (here und here).

Verwandte Themen