Asynchroner Download eines Azure-Blobs, der mit .NET 4.5 async als String interpretiert werden soll

9

Ich versuche, einen vollständig asynchronen Blob-Download mit .NET 4.5 async & amp; warte.

Nehmen wir an, der gesamte Blob kann sofort in den Speicher passen und wir möchten ihn in string speichern.

Code:

%Vor%

Verwendung:

%Vor%

Ist dieser Code korrekt und das ist in der Tat völlig asynchron? Würdest du das anders umsetzen?

Ich würde mich über zusätzliche Erläuterungen freuen:

  1. GetContainerReference und GetBlockBlobReference müssen nicht asynchron sein, da sie den Server noch nicht kontaktieren, oder?

  2. Muss streamReader.ReadToEnd asynchron sein oder nicht?

  3. Ich bin ein wenig verwirrt darüber, was BeginDownloadToStream macht .. Bis zu dem Zeitpunkt, an dem EndDownloadToStream aufgerufen wird, hat mein Speicherstrom all die Daten darin? oder ist der Stream nur vorgelesen?

Update: (ab Storage 2.1.0.0 RC)

Async wird jetzt nativ unterstützt.

%Vor%     
talkol 13.08.2013, 19:32
quelle

3 Antworten

13
  

Ist dieser Code korrekt und das ist in der Tat völlig asynchron?

Ja.

  

Würdest du das anders umsetzen?

Ja. Insbesondere sind die TaskFactory.FromAsync Wrapper viel effizienter, wenn Sie ein Begin / End Methodenpaar übergeben, anstatt einen vorhandenen IAsyncResult zu übergeben. So:

%Vor%

Ich bevorzuge es auch, diese in separate Erweiterungsmethoden einzubinden, so kann ich es so nennen:

%Vor%

Beachten Sie, dass die nächste Version der Clientbibliotheken (2.1, derzeit in RC) async -ready-Methoden haben wird, d. h. DownloadToStreamAsync .

  

GetContainerReference und GetBlockBlobReference müssen nicht asynchron sein, da sie den Server noch nicht kontaktieren, richtig?

Korrigieren.

  

Muss streamReader.ReadToEnd async sein oder nicht?

Es nicht (und sollte nicht). Stream ist ein ungewöhnlicher Fall mit async programing. Wenn es eine async -Methode gibt, sollten Sie diese normalerweise in Ihrem async -Code verwenden, aber diese Richtlinie gilt nicht für Stream -Typen. Der Grund dafür ist, dass die Base Stream -Klasse nicht weiß, ob ihre Implementierung synchron oder asynchron ist, also nimmt sie an, dass sie synchron ist und ihre asynchronen Operationen standardmäßig vortäuscht, indem sie nur die synchrone Arbeit an einem Hintergrund-Thread ausführt. Wirklich asynchrone Streams (z. B. NetworkStream ) überschreiben dies und stellen echte asynchrone Operationen bereit. Synchrone Streams (z. B. MemoryStream ) behalten dieses Standardverhalten bei.

Sie möchten also nicht ReadToEndAsync für MemoryStream aufrufen.

  

Ich bin ein wenig verwirrt darüber, was BeginDownloadToStream tut .. zu dem Zeitpunkt, zu dem EndDownloadToStream aufgerufen wird, hat mein Speicher-Stream alle Daten im Inneren?

Ja. Die Operation ist DownloadToStream ; dass es einen Blob in einen Stream herunterlädt. Da Sie einen Blob in ein MemoryStream herunterladen, befindet sich das Blob zum Zeitpunkt des Abschlusses dieses Vorgangs vollständig im Speicher.

    
Stephen Cleary 14.08.2013, 02:00
quelle
1
  1. Richtig, sie müssen nicht asynchron sein, wenn sie keine langen Operationen sind, was sie nicht sein sollten.

  2. Wahrscheinlich nicht, obwohl ich mit dieser speziellen Implementierung nicht vertraut bin. Ich würde hoffen, dass, da Sie darauf warten, dass der Stream vor diesem Punkt endet, keine Netzwerkarbeit und somit keine teuren Operationen an diesem Punkt ausgeführt werden sollten. Sie sollten nur Daten aus einem Puffer ziehen, und es sollte schnell sein. Dies ist jedoch leicht genug zu testen. Sie können etwas wie Fiddler verwenden, um zu sehen, ob während dieses Anrufs eine Netzwerkkommunikation stattfindet. Sie können die Methode einfach zeitlich festlegen, um zu sehen, ob die Netzwerk-E / A-Verarbeitung angezeigt wird, oder Sie können in den Dokumenten nachsehen spezifische Stream-Implementierung. Oder Sie könnten einfach die Async-Methode verwenden, um sicher zu sein, was ich vorschlagen würde, anstatt zu riskieren, sich zu irren. Ich wäre ziemlich überrascht zu finden, dass dies notwendig ist, um asynchron zu sein.

  3. Siehe # 2.

Servy 13.08.2013 19:54
quelle
0

Siehe: Ссылка für einige hilfreiche Best Practices, einschließlich Ihrer Gründe sollte vermeiden, Memory-Stream zu verwenden, wie der ursprüngliche Code :)

Eine Anmerkung ist, dass Sie zwei Hauptoptionen zum Herunterladen von Blobs, der Cloud [Block | Page] Blob.Download [Range] To * -Methoden und des von OpenRead () bereitgestellten Streams haben. Im Fall der Download-API wird der gesamte Blob (oder der Bereich, falls angefordert) als ein einziger GET-Aufruf ausgegeben, und die Ergebnisse werden an den geeigneten Ort gestreamt / geschrieben, im Fall eines vorübergehenden Fehlers ist der Teilbereich der noch nicht empfangenen Bytes entsprechend der Wiederholungsrichtlinie angefordert.

Die OpenRead-Methoden sind für Kunden gedacht, die Daten über einen längeren Zeitraum hinweg verarbeiten und keine Verbindung offen halten möchten. Sie arbeiten, indem sie eine gegebene Länge angeben, die auf der Client-Seite gepuffered wird, wenn der Strom aus vor gepufferten Daten ausläuft, wird der nächste Unterbereich angefordert.

Abschließend steht ab 2.1 RTM eine DownloadTextAsync-Methode zur Verfügung, die all das für Sie erledigt :) (mit optionalen Überladungen zur Angabe der Kodierung, Standard ist UTF8)

    
Joe Giardino 16.09.2013 23:03
quelle