为啥通过内存流上传 JSON 时 BlobClient.UploadAsync 会挂起?
Posted
技术标签:
【中文标题】为啥通过内存流上传 JSON 时 BlobClient.UploadAsync 会挂起?【英文标题】:Why does BlobClient.UploadAsync hang when uploading JSON via a memory stream?为什么通过内存流上传 JSON 时 BlobClient.UploadAsync 会挂起? 【发布时间】:2020-10-09 17:53:13 【问题描述】:我正在尝试通过内存流将 JSON 上传到 Azure blob。当我调用 UploadAsync 我的应用程序挂起。如果我将 UploadAsync 调用移到 StreamWriter 大括号之外,我会得到一个 System.ObjectDisposedException: 'Cannot access a closed Stream。'例外。如何将 JSON 流式传输到 blob?
var blobClient = new BlobClient(new Uri(storageUri), options);
var serializer = JsonSerializer.Create(this.serializerSettings);
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
serializer.Serialize(writer, job);
await blobClient.UploadAsync(stream, overwrite: true, cancellationToken: cancellationToken);
【问题讨论】:
1) 您需要在序列化后刷新StreamWriter
,最好将其放在using
语句中并且不关闭底层流(参见here)。 2)您需要在上传之前通过设置stream.Position = 0
来倒带MemoryStream
。不知道这些是否导致挂起。
似乎这是 Is there any way to close a StreamWriter without closing its BaseStream? 和 Stream.Seek(0, SeekOrigin.Begin) or Position = 0 的副本。 This answer 到 MemoryStream - Cannot access a closed Stream 准确显示了要做什么。同意吗?
感谢您的回复。我查看了那个帖子,但它没有显示正在刷新的流。
通过using
语句处理StreamWriter
会刷新它。链接的答案显示了如何在不关闭基础流的情况下做到这一点。
谢谢,我已经使用链接的答案更新了我的答案。
【参考方案1】:
我使用 leaveOpen 选项来保持内存流打开。在上传到 blob 之前,我还重绕了内存流。
var blobClient = new BlobClient(new Uri(storageUri), options);
var serializer = JsonSerializer.Create(this.serializerSettings);
using (var stream = new MemoryStream())
// Use the 'leave open' option to keep the memory stream open after the stream writer is disposed
using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
// Serialize the job to the StreamWriter
serializer.Serialize(writer, job);
// Rewind the stream to the beginning
stream.Position = 0;
// Upload the job via the stream
await blobClient.UploadAsync(stream, overwrite: true, cancellationToken: cancellationToken);
【讨论】:
以上是关于为啥通过内存流上传 JSON 时 BlobClient.UploadAsync 会挂起?的主要内容,如果未能解决你的问题,请参考以下文章