当前位置: 首页 > ds >正文

【26】C#实战篇—— 多个线程函数对同一个 Excel 文件进行写操作引起的文件冲突问题,解决方法

文章目录

  • 1 问题描述
  • 2 锁机制确保对Excel文件的写操作是线程安全的
  • 3 为什么是readonly?不是要写数据吗?

1 问题描述

现在cam1Func ~ cam5Func共5个相机测试的功能函数,C#开启5个线程同时运行这5个camFunc函数,

这5个camFunc都要调用 同一个名为 “Data_P0.xlsx"的Excel文件, 那么这就导致Data_P0.xlsx文件冲突

string m_ExcelName = "../Data/Data_P0.xlsx";public void Cam1Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[0]){m_Excel_Helper.SaveData(m_ExcelName, "cam1", "B6", BackVal, Variance, LWidth, spacingRows);isSaveData[0] = true;}// ...
}public void Cam2Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[1]){m_Excel_Helper.SaveData(m_ExcelName, "cam2", "B4", BackVal, Variance, LWidth, spacingRows);isSaveData[1] = true;}// ...
}public void Cam3Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[2]){m_Excel_Helper.SaveData(m_ExcelName, "cam3", "B2", BackVal, Variance, LWidth, spacingRows);isSaveData[2] = true;}// ...
}public void Cam4Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[3]){lock (excelLock){m_Excel_Helper.SaveData(m_ExcelName, "cam4", "F6", BackVal, Variance, LWidth, spacingRows);}isSaveData[3] = true;}// ...
}public void Cam5Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[4]){m_Excel_Helper.SaveData(m_ExcelName, "cam5", "F2", BackVal, Variance, LWidth, spacingRows);isSaveData[4] = true;}// ...
}

2 锁机制确保对Excel文件的写操作是线程安全的

为了解决同时对同一个 Excel 文件进行写操作引起的文件冲突问题,可以使用锁(lock)机制来确保每次只有一个线程能够访问文件。这样可以避免并发写入时的冲突。

可以使用 C# 中的 lock 关键字来实现这一点。下面是修改后的代码示例:

在类的开头定义这个静态锁对象,这个对象 是 Cam1Func 到 Cam5Func共用的;

// 定义一个静态对象用于锁
private static readonly object excelLock = new object();

然后在每个相机函数中使用这个锁对象来确保写操作是线程安全的。例如:

string m_ExcelName = "../Data/Data_P0.xlsx";public void Cam1Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[0]){// 使用锁机制确保对Excel文件的写操作是线程安全的,避免多线程并发写入时的冲突lock (excelLock){m_Excel_Helper.SaveData(m_ExcelName, "cam1", "B6", BackVal, Variance, LWidth, spacingRows);}isSaveData[0] = true;}// ...
}public void Cam2Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[1]){lock (excelLock){m_Excel_Helper.SaveData(m_ExcelName, "cam2", "B4", BackVal, Variance, LWidth, spacingRows);}isSaveData[1] = true;}// ...
}public void Cam3Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[2]){lock (excelLock){m_Excel_Helper.SaveData(m_ExcelName, "cam3", "B2", BackVal, Variance, LWidth, spacingRows);}isSaveData[2] = true;}// ...
}public void Cam4Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[3]){lock (excelLock){m_Excel_Helper.SaveData(m_ExcelName, "cam4", "F6", BackVal, Variance, LWidth, spacingRows);}isSaveData[3] = true;}// ...
}public void Cam5Func(bool isProcess, CancellationToken cancellationToken)
{// 类似的代码结构// ...if (LWidth[0] != 0 && !isSaveData[4]){lock (excelLock){m_Excel_Helper.SaveData(m_ExcelName, "cam5", "F2", BackVal, Variance, LWidth, spacingRows);}isSaveData[4] = true;}// ...
}

3 为什么是readonly?不是要写数据吗?

readonly 关键字用于确保 excelLock 对象在创建之后不能被更改。这是一个非常好的实践,因为锁对象不需要改变,只需要在多个线程之间共享它。将锁对象定义为 readonly 可以确保在整个应用程序运行期间它的引用不会被意外改变,从而避免潜在的线程安全问题。

与写/读数据无关,即使你要写数据,锁对象本身并不会存储数据或执行写操作。锁对象只是用于同步对资源的访问,确保每次只有一个线程能够访问该资源。在这种情况下,readonly 确保了锁对象在程序的生命周期内是唯一且不变的。

http://www.xdnf.cn/news/17522.html

相关文章:

  • Playwright C# 自动登录并上传 Excel 文件 的可运行示例
  • 十九、MySQL-DQL-基本查询
  • Python day39
  • Linux系统之lua 详解
  • 一周学会Matplotlib3 Python 数据可视化-标注 (Annotations)
  • 【线性代数】6二次型
  • Windows设置英文路径显示为中文名称的文件夹
  • Android 设置/修改系统NTP服务地址
  • Golang的本地缓存freecache
  • Nginx 功能扩展与二次开发实践
  • HUAWEI交换机命令基础
  • C++面向对象及其特性
  • AI 边缘计算网关:开启智能新时代的钥匙
  • Claude Code 的核心能力与架构解析
  • 【软考中级网络工程师】知识点之防火墙
  • CosyVoice 语音合成模型性能优化实战:从 CPU 瓶颈到 GPU 加速的完整解决方案
  • 北京JAVA基础面试30天打卡05
  • springBoot集成easyExcel 实现文件上传
  • 【Spring Boot启动流程底层源码详解】
  • 【从汇编语言到C语言编辑器入门笔记7】 - C语言编译器执行过程
  • Web3: 用ERC-1400革新公司股权激励
  • 【LeetCode 热题 100】(六)矩阵
  • 扩散LLM推理新范式:打破生成长度限制,实现动态自适应调节
  • 组合期权:垂直价差
  • 【股票数据API接口17】如何获取强势股池数据之Python、Java等多种主流语言实例代码演示通过股票数据接口获取数据
  • 【线性代数】线性方程组与矩阵——行列式
  • Red Hat Enterprise Linux 7.9安装Oracle 11.2.0.4单实例数据库-图文详解
  • Docker部署whisper转写模型
  • VS Git巨坑合并分支失败导致多项无关改变
  • urmom damn the jvm