.NET 5调用TextWriter/StreamWriter写数据抛出ArgumentOutOfRangeException问题咨询
根本原因
你遇到的这个异常90%以上是多线程并发访问同一个StreamWriter实例导致的,StreamWriter和其底层绑定的FileStream均不保证线程安全,并发写入会引发内部字段的竞争条件。
你虽然确认了实例未被释放、未被关闭,但只要存在多个线程同时调用_writer.WriteLine的场景,就会触发该问题。
异常触发的具体环节
你查看的.NET 5版本FlushWriteBuffer源码中,异常实际来自ReadOnlySpan<byte>的构造逻辑:
当并发写入时,多个线程会同时修改FileStream内部的_writePos(标识当前缓冲区已写入的字节数)字段,可能出现两种错误场景:
- 线程A刚判断完
_writePos != 0,还没构造ReadOnlySpan时,线程B修改了_writePos,使其值超过了内部缓冲区数组的总长度 - 线程A正在执行写入逻辑修改
_writePos的过程中,线程B读到了半更新的无效_writePos值
此时执行new ReadOnlySpan<byte>(GetBuffer(), 0, _writePos)时,第三个参数_writePos大于缓冲区数组的长度,ReadOnlySpan的构造函数会直接抛出ArgumentOutOfRangeException,该异常没有被FlushWriteBuffer捕获,就会沿着调用栈向上抛出。
而TextWriter.WriteLine的官方文档没有标注该异常,是因为文档描述的是单线程正常使用的场景,并发误用属于预期外的非法操作,不在常规异常的列举范围内。
修复方案
- 给
_writer.WriteLine的调用逻辑加锁,保证同一时间只有一个线程写入 - 改用线程安全的日志实现,比如直接使用.NET内置的
ILogger工厂实现,或者给你的SimpleFileLogger加线程同步逻辑
内容的提问来源于stack exchange,提问作者PMF
相关产品推荐
相关产品推荐

