讲师中心 微信公众号
AI工具推荐 视频效率加速

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

小宇同学_8666

小宇同学_8666

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

|

427人浏览过

|

来源于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 是关键:

  • 多个读者共存 → 用
    </li>
    <li>一个写者 + 多个读者 → 用 <code<FileShare.Read
    (写入方必须独占 Write,但允许别人只读)
  • 完全不允许并发 → 保持
    ,但要确保持有时间最短</li>
    </ul>
    <p>示例:<pre class='brush:php;toolbar:false;'>using var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.Read);
    这样别的进程还能 OpenRead,但不能 <code>OpenWrite

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

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

    解决思路一致:

    C#
    C#

    "避开 C# 常见错误——空陷阱、异步陷阱、LINQ 陷阱及资源泄漏。"

    下载
    • 对源文件,确认它没被其他程序以 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");<br>if (mutex.WaitOne(1000)) {<br>    try {<br>        File.AppendAllText(logPath, message);<br>    } finally {<br>        mutex.ReleaseMutex();<br>    }<br>} else {<br>    // 超时,说明别人正在写,可降级处理或抛自定义异常<br>}

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

热门AI工具

更多
墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

相关专题

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

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

3478

2023.08.10

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

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

503

2025.12.01

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

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

2187

2023.10.09

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

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

2753

2023.10.16

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

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

2073

2023.10.18

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

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

448

2023.10.31

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

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

3945

2024.04.10

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

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

8228

2024.04.10

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

0

2026.09.23

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn