0

0

C#文件锁定与解锁 C#如何处理文件并发访问冲突

月夜之吻

月夜之吻

发布时间:2026-02-11 09:42:10

|

347人浏览过

|

来源于php中文网

原创

应捕获 IOException 并指数退避重试,限3–5次,间隔从10ms逐次翻倍;仅捕获IOException,避免UnauthorizedAccessException;重试用Task.Delay;调整FileStream的FileShare参数以支持多读共存。

c#文件锁定与解锁 c#如何处理文件并发访问冲突

文件被占用时 IOException 怎么捕获和重试

直接对正在被其他进程或线程读写的文件调用 File.OpenFile.WriteAllText,大概率抛出 IOException:“The process cannot access the file 'xxx' because it is being used by another process.”。这不是异常逻辑错误,而是典型并发竞争现象。

正确做法不是回避,而是主动处理:用 try/catch 捕获 IOException,配合指数退避(exponential backoff)重试。注意不要无限制循环——建议最多 3–5 次,间隔从 10ms 开始逐次翻倍。

  • 只捕获 IOException,不捕获 UnauthorizedAccessException 等权限类异常,它们代表不同问题
  • 重试前加 Thread.Sleep 或更推荐的 await Task.Delay(异步上下文里)
  • 重试逻辑别塞进业务主流程,抽成独立方法,比如 RetryOnFileLockAsync

FileStream 构造时如何设置 FileShare 参数

根本原因常在于打开方式太“霸道”。默认 File.OpenRead(path) 等价于 new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None) —— 它禁止任何其他进程/线程同时访问该文件。

按实际协作需求调整 FileShare 是关键:

  • 多个读者共存 → 用
  • 一个写者 + 多个读者 → 用 (写入方必须独占 Write,但允许别人只读)
  • 完全不允许并发 → 保持
    ,但要确保持有时间最短

示例:

using var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.Read);
这样别的进程还能 OpenRead,但不能 OpenWrite

为什么 File.CopyFile.Move 也报文件锁定

很多人以为复制/移动是“原子操作”,不会冲突——其实不然。File.Copy 内部会先 Create 目标文件,再 Read 源文件流,全程可能被中断;File.Move 在跨卷时本质是“复制+删除”,同样涉及多次文件访问。

解决思路一致:

谱乐AI
谱乐AI

谱乐AI,集成 Suno、Udio 等顶尖AI音乐模型的一站式AI音乐生成平台。

下载
  • 对源文件,确认它没被其他程序以 FileShare.None 打开
  • 对目标路径,确保没有同名文件正被写入(比如日志轮转中未关闭的 StreamWriter
  • 跨进程场景下,优先考虑用命名互斥体(Mutex)协调,而不是靠重试硬扛

特别注意:Windows 中杀掉进程不一定立即释放句柄,尤其是 .NET 应用未显式 Dispose FileStreamStreamWriter 时,GC 回收前文件锁一直挂着。

Mutex 实现跨进程文件访问协调

当重试和 FileShare 都不够用(比如多个独立进程需严格串行写同一配置文件),就得上同步原语。Mutex 是 Windows 下最轻量、跨进程有效的选择。

关键点:

  • 名称必须全局唯一,建议带产品名/路径哈希,如 "Global\\MyApp_Config_Write_" + path.GetHashCode()
  • 务必用 try/finally 确保 mutex.ReleaseMutex() 被执行,否则死锁
  • 不要在 Mutex 持有期间做耗时操作(如网络请求、大文件读写),否则阻塞其他进程太久

示例节选:

var mutex = new Mutex(false, "Global\\MyApp_Log_Write");
if (mutex.WaitOne(1000)) {
try {
File.AppendAllText(logPath, message);
} finally {
mutex.ReleaseMutex();
}
} else {
// 超时,说明别人正在写,可降级处理或抛自定义异常
}

真正难的不是加锁,而是判断哪些操作必须串行、哪些可以并行,以及锁粒度是否合理——锁整个文件还是只锁某段内容,差别很大。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

633

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

91

2025.12.01

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

328

2023.10.09

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

420

2023.10.16

asp连接access数据库的方法
asp连接access数据库的方法

连接的方法:1、使用ADO连接数据库;2、使用DSN连接数据库;3、使用连接字符串连接数据库。想了解更详细的asp连接access数据库的方法,可以阅读本专题下面的文章。

122

2023.10.18

access和trunk端口的区别
access和trunk端口的区别

access和trunk端口的区别是Access端口用于连接终端设备,提供单个VLAN的接入,而Trunk端口用于连接交换机之间,提供多个VLAN的传输;Access端口只传输属于指定VLAN的数据,而Trunk端口可以传输多个VLAN的数据,并使用VLAN标签进行区分。想了解更多access和trunk端口相关内容,可以阅读本专题下面的文章。

333

2023.10.31

access怎么导入数据
access怎么导入数据

access导入数据步骤:1. 选择数据源 2. 选择要导入的文件 3. 指定导入选项 4. 选择导入目标 5. 预览数据 6. 导入数据即可。想了解更多access的相关内容,可以阅读本专题下面的文章。

445

2024.04.10

access数据库用途
access数据库用途

access数据库是一种关系型数据库管理系统,主要用途包括:数据存储和管理;数据查询和检索;报告和表单设计;应用程序开发。想了解更多access数据库的相关内容,可以阅读本专题下面的文章。

579

2024.04.10

包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法
包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法

本专题汇总了包子漫画官网和网页版入口,提供最新章节抢先看方法、正版免费阅读指南,以及稳定访问方式,帮助用户快速直达包子漫画页面,无广告畅享全集漫画内容。

50

2026.02.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.1万人学习

C 教程
C 教程

共75课时 | 4.6万人学习

C++教程
C++教程

共115课时 | 17.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号