C# Xamarin中SerializeAsync异步序列化报共享违规的解决方法
问题根因
共享违规错误、逻辑异常来自几个实现错误:
- 路径不一致:原同步代码判断
TempJsonPath()对应文件是否存在,写入时却用了PaymentCardListPath(),你写的异步版本直接写入TempJsonPath(),路径和业务逻辑不匹配 - 文件打开模式错误:使用
FileMode.Append追加模式,一方面会在文件末尾拼接新的JSON片段,生成不合法的JSON文件;另一方面默认构造的FileStream会对文件加独占锁,禁止其他线程/进程访问,极易触发共享冲突 - 资源未正确释放:声明的FileStream没有用异步释放语法包裹,操作完成后文件句柄不会被即时回收,会持续占用文件导致后续访问报错
- 逻辑判断冗余:原逻辑判断「临时文件存在才写入」本身不符合需求,写入操作不需要提前判断文件存在,文件流的创建模式会自动处理新建、覆盖逻辑
最佳异步实现
修正所有问题后的实现代码如下,兼容System.Text.Json的SerializeAsync异步序列化逻辑:
public static bool TempFileExists() { return File.Exists(TempJsonPath()); } public static async Task WriteToTempJsonAsync(DeclarationJoined declaration, CancellationToken ct = default) { // 替换为你实际要写入的目标路径,此处以写入临时JSON文件为例 var targetFilePath = TempJsonPath(); // 显式配置文件流参数,避免锁冲突、启用异步IO await using var fileStream = new FileStream( path: targetFilePath, mode: FileMode.Create, // 文件存在则覆盖,不存在则新建 access: FileAccess.Write, // 仅授予写权限 share: FileShare.Read, // 允许其他进程以只读方式打开文件,减少不必要的锁冲突 bufferSize: 4096, // 使用默认缓冲区大小 useAsync: true); // 启用原生异步IO,提升异步操作性能 // 执行异步序列化写入 await JsonSerializer.SerializeAsync(fileStream, declaration, cancellationToken: ct); // 确保内容完全刷入磁盘 await fileStream.FlushAsync(ct); }
实现注意事项
- 禁止用
FileMode.Append序列化完整JSON对象:JSON为单根结构,追加多个序列化结果会导致文件格式完全非法,仅逐行JSON日志这类特殊场景适合用追加模式 - 所有异步IO对象(如FileStream)必须用
await using声明,该语法会在代码块执行完成后自动异步释放文件句柄,从根源上避免文件句柄泄漏导致的占用报错 - 初始化FileStream时尽量显式指定
FileShare参数,默认的独占锁模式在多线程、多进程访问文件的场景下触发共享冲突的概率极高 - 可以根据业务需求给
SerializeAsync传入自定义的JsonSerializerOptions,比如设置格式化输出、命名策略等
内容的提问来源于stack exchange,提问作者Programming Teun
相关产品推荐
相关产品推荐

