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

【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.lryc.cn/news/615322.html

相关文章:

  • Playwright C# 自动登录并上传 Excel 文件 的可运行示例
  • Irix HDR Pro:专业级 HDR 图像处理软件
  • Docker部署whisper转写模型
  • Java中Lambda表达式的常见用法和解析:从入门到实战
  • C/C++基础详解(二)
  • 【51单片机4按键启动停止向上向下流水灯】2022-10-26
  • 本文章分享一个本地录音和实时传输录音给app的功能(杰理)
  • 【c++】探秘Loop机制:C++中优雅的双向数据交互模式
  • Ubuntu下安全彻底删除后端服务完整指南
  • 网络原理-初识
  • PNPM总结
  • QT第一讲- Qt初探
  • Microsoft Office Visio(流程图)学习笔记
  • 使用SymPy lambdify处理齐次矩阵的高效向量化计算
  • 动手学深度学习(pytorch版):第二章节——预备知识(1)——数据操作
  • 2025华数杯数学建模C题:可调控生物节律LED光源全解析
  • 理解协议最大传输单元(MTU)和TCP 最大报文段长度(MSS)
  • 自动生成视频的AI大模型高效创作指南
  • 掌握数据可视化:全局配置项详解
  • Nginx 反向代理与负载均衡架构
  • Redhat Linux 9.6 配置本地 yum 源
  • qt文件操作与qss基础
  • 2025彩虹易支付官方正版无删减完整版源码
  • B.10.01.5-电商系统的设计模式应用实战
  • 【Canvas与旗帜】圆角蓝底大黄白星十一红白带旗
  • Node.js特训专栏-实战进阶:22. Docker容器化部署
  • 北京JAVA基础面试30天打卡05
  • STM32的中断系统
  • 05.【数据结构-C语言】栈(先进后出,栈的实现:进栈、出栈、获取栈顶元素,栈实现代码,括号匹配问题)
  • 【排序算法】③直接选择排序