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

为何未手动释放StreamWriter时MemoryStream.ToArray()返回空数组

问题原因解析
  • 核心原因和StreamWriter的缓冲区机制、C# 8+ using var的释放时机有关
  • 首先StreamWriter写入内容时,数据会先存到内部缓冲区,默认缓冲区大小为4KB,只有缓冲区满、手动调用Flush()/Dispose()时,才会把缓冲区内容写入底层绑定的MemoryStream中。你写入的内容小于缓冲区阈值时,不会自动触发刷写操作。
  • 你使用的是C# 8引入的using var声明式语法,这种语法绑定的资源释放时机是变量离开当前作用域时,也就是整个方法执行完毕、return语句执行完成之后,才会调用StreamWriter的Dispose方法。你删除手动sw.Dispose()代码后,执行ms.ToArray()时StreamWriter还未被释放,缓冲区数据还没写入MemoryStream,自然拿到的就是空数组。
  • 你手动调用sw.Dispose()时,会立刻触发缓冲区刷写,把所有内容写入MemoryStream,所以能拿到正确的字节数组。
正确优化写法

你不需要手动调用Dispose,可以用两种方案解决问题:

  1. 调用Flush手动刷写缓冲区
public static byte[] GetByteArray(List<MyModel> models)
{
    using var ms = new MemoryStream();
    using var sw = new StreamWriter(ms);

    foreach (var model in models)
    {
        sw.WriteLine($"{model.Id},{model.Name}");
    }

    sw.Flush(); // 手动刷写缓冲区到MemoryStream
    return ms.ToArray();
}
  1. 使用块级using,保证StreamWriter在读取MemoryStream前就完成释放
public static byte[] GetByteArray(List<MyModel> models)
{
    using var ms = new MemoryStream();
    // 块级using,代码块结束时自动释放StreamWriter
    using (var sw = new StreamWriter(ms))
    {
        foreach (var model in models)
        {
            sw.WriteLine($"{model.Id},{model.Name}");
        }
    } // 此处StreamWriter已释放,缓冲区已刷入MemoryStream
    return ms.ToArray();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 12:54:08