13

.NET 4.5 async & await を使用して、完全に非同期の BLOB ダウンロードを実装しようとしています。

ブロブ全体が一度にメモリに収まり、string.

コード:

public async Task<string> DownloadTextAsync(ICloudBlob blob)
{
    using (Stream memoryStream = new MemoryStream())
    {
        IAsyncResult asyncResult = blob.BeginDownloadToStream(memoryStream, null, null);
        await Task.Factory.FromAsync(asyncResult, (r) => { blob.EndDownloadToStream(r); });
        memoryStream.Position = 0;

        using (StreamReader streamReader = new StreamReader(memoryStream))
        {
            // is this good enough?
            return streamReader.ReadToEnd();

            // or do we need this?
            return await streamReader.ReadToEndAsync();
        }
    }
}

使用法:

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageAccountConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("container1");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1.txt");

string text = await DownloadTextAsync(blockBlob);

このコードは正しく、これは実際に完全に非同期ですか? これを別の方法で実装しますか?

いくつかの追加の説明をいただければ幸いです。

  1. GetContainerReferenceGetBlockBlobReferenceまだサーバーに接続していないので、非同期である必要はありませんよね?

  2. streamReader.ReadToEnd非同期である必要がありますか?

  3. 私は何をしているのか少し混乱してBeginDownloadToStreamいます..EndDownloadToStream呼び出されるまでに、メモリストリームにはすべてのデータが含まれていますか? または、ストリームは事前読み取りのみを開いていますか?

更新: (Storage 2.1.0.0 RC 以降)

非同期がネイティブでサポートされるようになりました。

CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageAccountConnectionString"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("container1");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("blob1.txt");

string text = await blockBlob.DownloadTextAsync();
4

3 に答える 3

0

元のコードのようにメモリ ストリームの使用を避けるべき理由など、役立つベスト プラクティスについては、 http: //channel9.msdn.com/Events/TechEd/NorthAmerica/2013/WAD-B406#fbid=lCN9J5QiTDFを参照してください:)

Blob をダウンロードするには、Cloud[Block|Page]Blob.Download[Range]To* メソッドと OpenRead() によって提供されるストリームの 2 つの主なオプションがあることに注意してください。ダウンロード API の場合、BLOB 全体 (または要求された場合は範囲​​) が単一の GET 呼び出しとして発行され、結果が適切な場所にストリーミング/書き込まれます。一時的な障害の場合、まだ受信されていないバイトの部分範囲は再試行ポリシーに従って要求されます。

OpenRead メソッドは、長期間にわたってデータを処理し、接続を開いたままにしたくないクライアントを対象としています。これらは、クライアント側で事前にバッファーされる特定の長さを指定することによって機能します。ストリームが事前にバッファーされたデータを使い果たすと、次のサブ範囲が要求されます。

最後に、2.1 RTMの時点で、これをすべて行う DownloadTextAsync メソッドが提供されています :) (エンコーディングを指定するオプションのオーバーロードを使用すると、デフォルトは UTF8 です)

于 2013-09-16T23:03:34.620 に答える