2024年支持6线程并行写入文件的C#类选型咨询
多线程并行写入文件的C#解决方案(适配6个NUnit测试场景)
针对你提到的6个并行NUnit测试线程追加写入同一文件的场景,2024年有多个可靠的.NET原生方案可以解决,以下是最实用的几种:
1. 轻量排他锁:SemaphoreSlim
适合异步测试场景,能安全控制并发写入,避免锁异常:
// 全局静态信号量,确保所有测试线程共享 private static readonly SemaphoreSlim _fileWriteSemaphore = new SemaphoreSlim(1, 1); public static async Task WriteTestLogAsync(string logFilename, string testName, DateTime startTime) { await _fileWriteSemaphore.WaitAsync(); try { using var writer = new StreamWriter(logFilename, append: true); await writer.WriteLineAsync($"[{startTime:yyyy-MM-dd HH:mm:ss.fff}] 测试启动: {testName}"); } finally { // 确保锁一定会释放,避免死锁 _fileWriteSemaphore.Release(); } }
优势:异步友好,不会阻塞测试线程;锁逻辑清晰,避免Monitor.TryEnter可能出现的未释放锁异常。
2. 极简方案:File.AppendAllTextAsync
.NET内置方法,已封装安全追加逻辑,适合低并发(6个线程)场景:
public static async Task WriteTestLogAsync(string logFilename, string testName, DateTime startTime) { string logLine = $"[{startTime:yyyy-MM-dd HH:mm:ss.fff}] 测试启动: {testName}{Environment.NewLine}"; await File.AppendAllTextAsync(logFilename, logLine); }
优势:代码极简,无需手动管理锁;内部已处理文件打开/关闭的安全逻辑,足够应对6个并行测试的写入需求。
3. 读写分离优化:ReaderWriterLockSlim
如果后续需要兼顾文件读取,这个类能在保证写排他的同时,允许多个线程并发读取:
private static readonly ReaderWriterLockSlim _fileLock = new ReaderWriterLockSlim(); public static void WriteTestLog(string logFilename, string testName, DateTime startTime) { _fileLock.EnterWriteLock(); try { using var writer = new StreamWriter(logFilename, append: true); writer.WriteLine($"[{startTime:yyyy-MM-dd HH:mm:ss.fff}] 测试启动: {testName}"); } finally { _fileLock.ExitWriteLock(); } }
优势:读写场景下性能更优;同步版本适合非异步的NUnit测试方法。
关于你之前方案的问题解析
- 直接使用
FileStream带FileShare.Write:多个线程同时写入时,缺乏排他控制,会导致写入内容重叠、截断,出现文本不完整的情况。 Monitor.TryEnter出现异常:通常是锁对象未全局共享(比如用了局部变量),或者异常导致锁未释放,只要确保锁对象是静态全局的,并在finally块中释放,就能避免问题。
内容的提问来源于stack exchange,提问作者gords
相关产品推荐
相关产品推荐

