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

将using块内的MemoryStream传参后第二次调用时提示流已关闭

问题原因
  • 第一个核心原因是你第一次调用UploadImageAsync(memoryStream, false)时,内部UploadAsync方法调用的fileTransferUtility.UploadAsync默认会在上传完成后自动释放传入的流,导致你外层using块里的memoryStream在第一次调用结束后就已经被关闭,第二次调用传入时自然抛出「无法访问已关闭的流」错误。
  • 就算你解决了流自动释放的问题,还存在第二个隐藏问题:第一次读取流之后,流的Position属性会停在流的末尾,第二次直接传入Image.FromStream时,方法从末尾开始读不到有效内容,也会抛出异常。
修复方案

方案1:复用同一个流(性能更高)

  1. 检查你使用的fileTransferUtility.UploadAsync方法的参数,找到leaveOpen(多数云存储SDK都提供该参数)相关配置,设置为true,让方法上传完成后不自动释放传入的流。
  2. 每次使用流之前,都将流的位置重置到开头,添加stream.Position = 0代码。
    修复后的核心代码示例:
public async Task UploadObject(IFormFile file, string prefix)
{
    using (var memoryStream = new MemoryStream())
    {
        file.CopyTo(memoryStream);
        // 第一次调用前重置位置
        memoryStream.Position = 0;
        await UploadImageAsync(memoryStream, false);
        // 第二次调用前重置位置
        memoryStream.Position = 0;
        await UploadImageAsync(memoryStream, true);
    }
}

public async Task UploadImageAsync(MemoryStream stream, bool process)
{
    if (process)
    {
        // 这里也可以再加一次Position重置,双重保险
        stream.Position = 0;
        using (Image orginalImage = Image.FromStream(stream))
        {
            using (Bitmap bitmapResized = new Bitmap(orginalImage, newWidth, newHeight))
            {
                using (MemoryStream streamResized = new MemoryStream())
                {
                    bitmapResized.Save(streamResized, orginalImage.RawFormat);
                    streamResized.Position = 0;
                    await UploadAsync(streamResized);
                }
            }
        }
    }
    else
    {
        await UploadAsync(stream);
    }

    async Task UploadAsync(MemoryStream stream)
    {
        // 构造uploadRequest时指定leaveOpen = true,避免流被自动释放
        var uploadRequest = new 你的上传请求类
        {
            // 其他参数
            LeaveOpen = true
        };
        await fileTransferUtility.UploadAsync(uploadRequest);
    }
}

方案2:每次使用独立的流(更稳妥,无副作用)

直接提前把流内容转成字节数组,每次调用都用字节数组创建新的MemoryStream,完全避免流被共享操作导致的问题:

public async Task UploadObject(IFormFile file, string prefix)
{
    using (var memoryStream = new MemoryStream())
    {
        file.CopyTo(memoryStream);
        var fileBytes = memoryStream.ToArray();
        // 第一次调用用新的流
        using var stream1 = new MemoryStream(fileBytes);
        await UploadImageAsync(stream1, false);
        // 第二次调用用新的流
        using var stream2 = new MemoryStream(fileBytes);
        await UploadImageAsync(stream2, true);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:18:02