使用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不会被关闭/释放吗?
只要不将内存流包装在"using"语句中,就可以了。如果你真的使用"using",你最终会遇到一种奇怪的比赛条件,有时它有效,有时却失败。我有像你这样的代码在生产中,它工作得很好。
唯一需要注意的是,在将任何内容发送到客户端之前,将整个blob复制到内存中。这可能会导致服务器内存压力和初始滞后,具体取决于文件的大小。如果这是一个问题,你有几个选择。一种是在blob上创建一个"租约",并为用户提供一个URL,以便在有限的时间内直接从blob存储中读取。不过,这只适用于低安全性的场景。
或者,您可以使用分块传输编码。基本上,您从blob存储中以块的形式读取文件,并以这些块的形式将其发送到客户端。这样可以节省内存,但我无法使其异步工作,所以您正在用内存换取线程。哪种解决方案对你来说是正确的取决于你的具体情况。
(我手头没有代码,如果你想要的话,可以发表评论,我会努力把它挖出来,即使它有点旧)。