C#_定时器_解析

问题一:这里加lock是啥意思?它的原理是, 为什么可以锁住?

private readonly Timer _timer;/// <summary>/// 构造函数中初始化定时器/// </summary>public FtpTransferService(){// 初始化定时器_timer = new Timer(_intervalMinutes * 60 * 1000);_timer.Elapsed += OnTimerElapsed;//绑定定时触发的事件_timer.AutoReset = true;//定时器的属性,控制是否在每次间隔后重复触发事件}/// <summary>/// 定时器触发事件 - 增加锁防止并发/// </summary>private void OnTimerElapsed(object sender, ElapsedEventArgs e){lock (_lock){try{WriteLog($"开始执行文件转移任务({DateTime.Now:yyyy-MM-dd HH:mm:ss})");// 遍历所有目录(包括非最内层)并复制结构TransferAllDirectories(_sourceRootPath);WriteLog($"文件转移任务执行完成({DateTime.Now:yyyy-MM-dd HH:mm:ss})");}catch (Exception ex){WriteLog($"任务执行异常:{ex.Message}\r\n堆栈:{ex.StackTrace}", isError: true);}}}

在这段代码中,lock (_lock) 的作用是防止定时器事件被并发执行,确保 OnTimerElapsed 方法中的逻辑在同一时间只能被一个线程执行。

为什么需要加 lock

System.Timers.TimerElapsed 事件默认由线程池线程触发。如果定时任务(如代码中的 TransferAllDirectories)的执行时间超过了定时器的间隔时间,就会出现以下问题:

  • 第一个任务还没执行完,第二个定时器事件就被触发,导致两个线程同时执行 OnTimerElapsed 中的逻辑。
  • 这可能引发资源竞争(如同时操作同一文件/目录),导致数据错乱或异常。

lock 的作用就是保证同一时间只有一个线程能进入被锁定的代码块,避免这种并发冲突。

lock 的工作原理

lock 本质上是基于 .NET 的** Monitor 同步机制**实现的,其核心逻辑可以简化为:

  1. 当线程进入 lock (_lock) 代码块时,会尝试获取 _lock 对象的「独占锁」。
  2. 如果锁未被占用,当前线程会获取锁并执行代码块。
  3. 如果锁已被其他线程占用,当前线程会进入阻塞状态,等待锁被释放。
  4. 当线程执行完代码块后,会自动释放锁,让其他等待的线程可以获取锁并执行。

为什么用 _lock 这个对象?

lock 需要一个「同步对象」(这里是 _lock),它的作用是:

  • 作为锁的「标识」,不同的同步对象对应不同的锁。
  • 必须是引用类型(如 object),因为值类型会被装箱,每次 lock 都会创建新对象,导致锁失效。
  • 通常定义为 private readonly,确保:
    • 外部代码无法访问该对象(避免外部误操作导致锁失控)。
    • 对象引用不会被修改(保证始终用同一个对象作为锁标识)。

这段代码中 lock 的实际效果

假设定时器间隔为 5 分钟,但 TransferAllDirectories 某次执行花了 7 分钟:

  • 第一个线程在第 0 分钟进入代码块,获取 _lock 锁。
  • 第 5 分钟时,定时器再次触发 Elapsed 事件,第二个线程尝试进入代码块,但此时锁被第一个线程占用,只能等待。
  • 第 7 分钟,第一个线程执行完并释放锁,第二个线程立即获取锁并开始执行。

这样就避免了两个线程同时执行文件转移逻辑,保证了操作的安全性。

注意点

  • lock 会导致等待的线程阻塞,因此被锁定的代码块应尽量简短,避免长时间占用锁影响性能。
  • 不要用 stringthis 作为同步对象:string 有字符串驻留机制,可能导致不同地方的锁冲突;this 可能被外部代码访问,存在安全风险。
  • 此代码中 _timer.AutoReset = true 表示定时器会重复触发,结合 lock 可以完美解决「任务执行时间超过间隔」的并发问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90297.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Trae开发uni-app+Vue3+TS项目飘红踩坑

前情 Trae IDE上线后我是第一时间去使用体验的&#xff0c;但是因为一直排队问题不得转战Cursor&#xff0c;等到Trae出付费模式的时候&#xff0c;我已经办了Cursor的会员&#xff0c;本来是想等会员过期了再转战Trae的&#xff0c;但是最近Cursor开始做妖了 网上有一堆怎么…

低代码中的统计模型是什么?有什么作用?

低代码开发平台中的统计模型是指通过可视化配置、拖拽操作或少量代码即可应用的数据分析工具&#xff0c;旨在帮助技术人员及非技术人员快速实现数据描述、趋势预测和业务决策。其核心价值在于降低数据分析门槛&#xff0c;使业务人员无需深入掌握统计原理或编程技能&#xff0…

Linux 下在线安装启动VNC

描述 Linux中的VNC就类似于Windows中的远程桌面系统 本文只记录在Cent OS 7的系统下在线安装VNC。 安装VNC 1、安装VNC yum install tigervnc-server2、配置VNC的密码 为用户设置 VNC 密码&#xff08;首次运行会提示输入&#xff0c;也可以提前输入&#xff09; vncpasswd密码…

支持OCR和AI解释的Web PDF阅读器:解决大文档阅读难题

支持OCR和AI解释的Web PDF阅读器&#xff1a;解决大文档阅读难题一、背景&#xff1a;为什么需要这个工具&#xff1f;问题场景解决方案二、技术原理&#xff1a;如何实现这些功能&#xff1f;1、核心技术组件2、工作流程3、关键点三、操作指南1、环境准备2、生成Html代码3、We…

研发过程都有哪些

产品规划与定义 (Product Planning & Definition) 在详细的需求调研之前&#xff0c;通常会进行市场分析、竞品分析、确立产品目标和核心价值。这个阶段决定了“我们要做什么”以及“为什么要做”。 系统设计与架构 (System & Architectural Design) 这是开发的“蓝图”…

旧物回收小程序系统开发——开启绿色生活新篇章

在当今社会&#xff0c;环保已经成为全球关注的焦点话题。随着人们生活水平的提高&#xff0c;消费能力不断增强&#xff0c;各类物品的更新换代速度日益加快&#xff0c;大量旧物被随意丢弃&#xff0c;不仅造成了资源的巨大浪费&#xff0c;还对环境产生了严重的污染。在这样…

UE5 UI 水平框

文章目录slot区分尺寸和对齐方式尺寸&#xff1a;自动模式尺寸&#xff1a;填充模式对齐常用设置所有按钮大小一致&#xff0c;不受文本影响靠右排列和unity的HorizontalLayout不太一样slot 以在水平框中放入带文字的按钮为例 UI如下布置 按钮的大小受slot的尺寸、对齐和内部…

【Golang】Go语言变量

Go语言变量 文章目录Go语言变量一、Go语言变量二、变量声明2.1、第一种声明方式2.2、第二种声明方式2.3、第三种声明方式2.4、多变量声明2.5、打印变量占用字节一、Go语言变量 变量来源于数学&#xff0c;是计算机语言中能存储计算结果或能表示值抽象的概念变量可以通过变量名…

Qt WebEngine Widgets的使用

一、Qt WebEngine基本概念Qt WebEngine中主要分为三个模块&#xff1a;Qt WebEngine Widgets模块&#xff0c;主要用于创建基于C Widgets部件的Web程序&#xff1b;Qt WebEngine模块用来创建基于Qt Quick的Web程序&#xff1b;Qt WebEngine Core模块用来与Chromeium交互。网页玄…

【C++】标准模板库(STL)—— 学习算法的利器

【C】标准模板库&#xff08;STL&#xff09;—— 学习算法的利器学习 STL 需要注意的几点及 STL 简介一、什么是 STL&#xff1f;二、学习 STL 前的先修知识三、STL 常见容器特点对比四、学习 STL 的关键注意点五、STL 学习路线建议六、总结七、下一章 vector容器快速上手学习…

YOLO算法演进综述:从YOLOv1到YOLOv13的技术突破与应用实践,一文掌握YOLO家族全部算法!

引言&#xff1a;介绍目标检测技术背景和YOLO算法的演进意义。YOLO算法发展历程&#xff1a;使用阶段划分方式系统梳理各代YOLO的技术演进&#xff0c;包含早期奠基、效率优化、注意力机制和高阶建模四个阶段。YOLOv13的核心技术创新&#xff1a;详细解析HyperACE机制、FullPAD…

快速将前端得依赖打为tar包(yarn.lock版本)并且推送至nexus私有依赖仓库(笔记)

第一步创建js文件 文件名为downloadNpmPackage.jsprocess.env.NODE_TLS_REJECT_UNAUTHORIZED "0";const fs require("fs"); const path require("path"); const request require("request");// 设置依赖目录 const downUrl "…

Unity VS Unreal Engine ,“电影像游戏的时代” 新手如何抉择引擎?(结)

Unity VS Unreal Engine &#xff0c;“电影像游戏的时代” 新手如何抉择引擎&#xff1f;(1)-CSDN博客 这是我的上一篇文章&#xff0c;如果你仍然困惑选择引擎的事情&#xff0c;我们不妨从别的方面看看 注意&#xff1a;我们可能使用"UE5"来表示Unreal Engine系…

EVAL长度限制突破方法

EVAL长度限制突破方法 <?php $param $_REQUEST[param]; If (strlen($param) < 17 && stripos($param, eval) false && stripos($param, assert) false) //长度小于17&#xff0c;没有eval和assert关键字 {eval($param); } //stripos — 查找字符串…

Linux部署.net Core 环境

我的环境 直接下载安装就可以了 wget https://builds.dotnet.microsoft.com/dotnet/Sdk/8.0.315/dotnet-sdk-8.0.315-linux-x64.tar.gzmkdir -p $HOME/dotnet && tar zxf dotnet-sdk-8.0.315-linux-x64.tar.gz -C $HOME/dotnet export DOTNET_ROOT$HOME/dotnet expor…

ARM-定时器-PWM通道输出

学习内容需求点亮4个灯&#xff0c;采用pwm的方式。定时器通道引脚AFLED序号T3CH0PD12AF2LED5CH1PD13AF2LED6CH2PD14AF2LED7CH3PD15AF2LED8实现LED5, LED6, LED7, LED8呼吸灯效果通用定时器多通道点亮T3定时器下的多个通道的灯。开发流程添加Timer依赖初始化PWM相关GPIO初始化P…

javaSE(List集合ArrayList实现类与LinkedList实现类)day15

目录 List集合&#xff1a; 1、ArrayList类&#xff1a; &#xff08;1&#xff09;数据结构&#xff1a; &#xff08;2&#xff09;扩容机制 &#xff08;3&#xff09;ArrayList的初始化&#xff1a; &#xff08;4&#xff09;ArrayList的添加元素方法 &#xff08;5…

解决 WSL 中无法访问 registry-1.docker.io/v2/,无法用 docker 拉取 image

文章目录无法拉取docker镜像补充迁移 WSL 位置Install Docker无法拉取docker镜像 docker run hello-world Unable to find image hello-world:latest locally docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline excee…

【C++】简单学——list类

模拟实现之前需要了解的概念带头双向链表&#xff08;double-linked&#xff09;&#xff0c;允许在任何位置进行插入区别相比vector和string&#xff0c;多了这个已经没有下标[ ]了&#xff0c;因为迭代器其实才是主流&#xff08;要包头文件<list>&#xff09;方法构造…

Qt 国际化与本地化完整解决方案

在全球化的今天&#xff0c;软件支持多语言和本地化&#xff08;Internationalization & Localization&#xff0c;简称i18n & l10n&#xff09;已成为基本需求。Qt提供了一套完整的解决方案&#xff0c;帮助开发者轻松实现应用程序的国际化支持。本文将从原理到实践&a…