You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BlobClient.UploadAsync上传JSON内存流时挂起及流已释放异常求助

解决JSON流式上传至Azure Blob的问题

看来你碰到了流操作里常见的两个坑:要么上传时挂起,要么流被提前关闭抛异常。我来给你拆解原因,再给几个靠谱的解决方案~

问题根源分析

  1. 在StreamWriter块内调用UploadAsync导致挂起:
    当你用serializer.Serialize(writer, job)写完JSON后,MemoryStream的当前位置会停在内容末尾,而UploadAsync是从当前位置开始读取流的,自然读不到任何数据,就会一直等待,导致程序挂起。另外,StreamWriter默认会缓冲内容,可能还有部分数据没刷到MemoryStream里。

  2. 移到StreamWriter块外抛出ObjectDisposedException:
    默认情况下,StreamWriter的Dispose方法会关闭它所包装的底层流(也就是你的MemoryStream)。当你把UploadAsync移到using块外时,MemoryStream已经被关闭,自然无法访问。

解决方案

方案一:修复流位置与StreamWriter的Dispose行为(适配你的原有代码)

调整代码,确保流的位置正确,并且StreamWriter不会提前关闭MemoryStream:

var blobClient = new BlobClient(new Uri(storageUri), options);
var serializer = JsonSerializer.Create(this.serializerSettings);
using (var stream = new MemoryStream()) {
    // 关键:设置leaveOpen: true,让StreamWriter dispose时不关闭底层流
    using (var writer = new StreamWriter(stream, leaveOpen: true)) {
        serializer.Serialize(writer, job);
        // 强制把StreamWriter缓冲区的内容刷入MemoryStream
        writer.Flush();
        // 把流的位置重置到开头,让UploadAsync能读到完整的JSON
        stream.Position = 0;
        await blobClient.UploadAsync(stream, overwrite: true, cancellationToken: cancellationToken);
    }
}

方案二:用SDK自带的序列化上传(最简洁)

Azure.Storage.Blobs库已经封装了直接序列化对象到Blob的方法,完全不用手动处理流:

var blobClient = new BlobClient(new Uri(storageUri), options);
await blobClient.UploadAsync(
    BinaryData.FromObjectAsJson(job, this.serializerSettings),
    overwrite: true,
    cancellationToken: cancellationToken);

这种方式由SDK帮你处理所有流的细节,代码更简洁,也不容易出错。

方案三:直接写入Blob的上传流(适合大对象)

如果你的JSON对象很大,不想占用内存中转,可以直接打开Blob的写入流,把序列化内容直接写进去:

var blobClient = new BlobClient(new Uri(storageUri), options);
var serializer = JsonSerializer.Create(this.serializerSettings);
// 直接打开Blob的写入流
using (var uploadStream = await blobClient.OpenWriteAsync(overwrite: true, cancellationToken: cancellationToken))
using (var writer = new StreamWriter(uploadStream)) {
    serializer.Serialize(writer, job);
    // StreamWriter的Dispose会自动Flush缓冲区,无需手动操作
}

这种方式节省内存,适合处理大文件或大对象。

内容的提问来源于stack exchange,提问作者Dave Moran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:12:29