問題描述
將 Azure Blob 中的數據流式傳輸回客戶端 (Streaming Data from Azure Blobs Back to Client)
使用 ASP.Net Web API,我正在開發一項服務,該服務(除其他外)從 Azure 檢索數據,並將其返回給客戶端。
這樣做的一種方法是讀取netire blob 寫入緩衝區,然後將該緩衝區寫入響應。但是,我寧願流式傳輸內容,以獲得更好的性能。
Azure API 很簡單:
CloudBlobContainer container = BlobClient.GetContainerReference(containerName);
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
using (var buffer = new MemoryStream())
{
await blob.DownloadToStreamAsync(buffer);
}
在代碼的其他地方,這會返回給客戶端:
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StreamContent(buffer);
但是我可以確定在客戶端完成讀取之前 MemoryStream 不會被關閉/處置嗎?
參考解法
方法 1:
As long as you don't wrap your memory stream in a "using" statement you will be fine. If you do use "using" you end up with a weird race condition where it works sometimes and fails at other times. I have code like yours in production and it works fine.
Only thing to be mindful of is that the whole blob is copied into memory before anything is sent to the client. This may cause memory pressures on your server and initial lag, depending on the size of the file. If that is a concern, you have a couple of options. One is to create a "lease" on the blob and give the user a URL to read it direct from blob storage for a limited time. That only works for low security scenarios though.
Alternatively you can use chunked transfer encoding. Basically, you read the file from blob storage in chunks and sends it to the client in those chunks. That saves memory ‑ but I have not been able to make it work async, so you are trading memory for threads. Which is the right solution for you will depend in your specific circumstances.
(I have not got the code to hand, post a comment if you want it and I'll try to dig it out, even if it's a bit old).