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

C# 定时器封装版

一、概述

在 Winform 等平台开发中,经常会用到定时器的功能,但项目定时器一旦写多了,容易使软件变卡,而且运行时间长了会造成软件的闪退,这个可能是内存溢出造成的,具体原因我也没去深究,另一个,就是在关闭软件时,经常关不掉,因为这时候定时器的线程依然还在运行,你就要把这些定时器一个个关闭,才能关闭软件,或者直接使用强制退出程序代码,非常的麻烦,后面我在想能不能封装一个定时器,使用事件的订阅机制来实现功能,后面就实现了这些功能,那么下面就开始搬代码吧。

二、实现功能

新建一个 winform 项目,添加一个类 ScanTimer.cs  。

代码:

using System;
using System.Threading;/// <summary>
/// 定时器
/// </summary>
public class ScanTimer
{/// <summary>/// 定时器回调事件/// </summary>public static event Action ScanEvent;/// <summary>/// 定时器开关的状态/// </summary>public static Action<bool> TimerStatus = null;/// <summary>/// 定时器执行的次数/// </summary>public static Action<int> TimerExecuteCount = null;/// <summary>/// 定时器是否打开/// </summary>public static bool IsOpen{get{if (Timer == null)return false;return Timer.Enabled;}}//定时器private static System.Timers.Timer Timer = null;//间隔时间private const int IntervalTime = 2000;//定时清理控制台日志private static int OutCount = 0;//是否初始化private static bool IsInit = false;/// <summary>/// 初始化/// </summary>private static void Init(){//实例化Timer类,Timer = new System.Timers.Timer();//设置间隔时间(毫秒);Timer.Interval = IntervalTime;//到达时间的时候执行事件;Timer.Elapsed += new System.Timers.ElapsedEventHandler(Elapsed);//设置是执行一次(false)还是一直执行(true);Timer.AutoReset = true;IsInit = true;}/// <summary>/// 定时器/// </summary>/// <param name="source"></param>/// <param name="e"></param>private static void Elapsed(object source, System.Timers.ElapsedEventArgs e){OutCount++;if (OutCount > 10000){OutCount = 0;//Console.Clear();}//定时器的执行次数if (TimerExecuteCount != null)TimerExecuteCount(OutCount);//执行回调if (ScanEvent != null)ScanEvent();}/// <summary>/// 打开定时器/// </summary>public static void Start(){if (!IsInit) Init();Timer.Enabled = true;OutCount = 0;if (TimerStatus != null)TimerStatus(true);}/// <summary>/// 关闭定时器/// </summary>public static void Stop(){Timer.Enabled = false;OutCount = 0;if (TimerStatus != null)TimerStatus(false);}/// <summary>/// 清除所有的事件/// </summary>public static void ClearAllEvent(){if (ScanEvent == null) return;Delegate[] dels = ScanEvent.GetInvocationList();foreach (Delegate del in dels){ScanEvent -= del as Action;}Console.WriteLine("[ClearAllEvent]清除定时器所有的事件");}/// <summary>/// 获取定时器任务的个数/// </summary>/// <returns></returns>public static int GetTaskCount(){if (ScanEvent == null) return 0;Delegate[] dels = ScanEvent.GetInvocationList();return dels.Length;}/// <summary>/// 是否存在某个任务/// </summary>/// <param name="taskName"></param>/// <returns></returns>public static bool IsExistTask(string taskName){if (ScanEvent == null)return false;Delegate[] dels = ScanEvent.GetInvocationList();foreach (Delegate del in dels){object delObj = del.GetType().GetProperty("Method").GetValue(del, null);string funcName = (string)delObj.GetType().GetProperty("Name").GetValue(delObj, null);if (funcName == taskName) return true;}return false;}private ScanTimer() { }
}

给 Form1 窗体添加 Form1_Load,Form1_FormClosing 事件。

Form1_Load 事件是窗体启动时执行一次,在这里可以启动定时器。

Form1_FormClosing 事件是在窗体关闭时执行一次,在这里我们可以关闭定时器。

如下图:

 

三、测试

ScanTimer 的 ScanEvent 字段是一个事件,这里就是我们需要添加订阅机制的地方。

public static event Action ScanEvent;

其实原理也很简单,就是在 ScanTimer 类中封装一个定时器,每隔多少秒去执行一次这个事件,然后所有订阅这个事件的方法,都会被执行到。

在调用 ScanTimer 类之前,先把 winform 的输出类型改为 控制台应用程序,这样更方便的观察。

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 定时器
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){ScanTimer.ScanEvent += Timer;ScanTimer.Start();}private void Form1_FormClosing(object sender, FormClosingEventArgs e){ScanTimer.Stop();}private void Timer(){Console.WriteLine("定时器");}}
}

调用也非常的简单,只需要写一个 Timer() 方法,然后添加到 ScanEvent 这个事件中就好了,我们运行看看效果

另外,在 ScanTimer 类中我还封装了其他的方法,比如,你不知道定时器是否还在执行中,有时候执行代码,不一定需要在代码中打印, 可以使用 TimerExecuteCount 这个委托查看定时器执行了多少次,也可以通过 TimerStatus 这个委托,来查看定时器是否在执行。

代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace 定时器
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){ScanTimer.ScanEvent += Timer;ScanTimer.TimerStatus += TimerStatus;ScanTimer.TimerExecuteCount += TimerExecuteCount;ScanTimer.Start();}private void Form1_FormClosing(object sender, FormClosingEventArgs e){ScanTimer.Stop();}private void Timer(){Console.WriteLine("定时器");}private void TimerStatus(bool sw){Console.WriteLine("定时器的状态:{0}", sw);}private void TimerExecuteCount(int count){Console.WriteLine("定时器执行次数:{0}", count);}}
}

运行:

在这里,TimerExecuteCount 和 TimerStatus 这两个委托是 Action 类型,如果其他的类不需要订阅这两个委托,不用使用 += ,可以直接使用 = 号就行。

ScanTimer.ScanEvent += Timer;
ScanTimer.TimerStatus = TimerStatus;
ScanTimer.TimerExecuteCount = TimerExecuteCount;

 

结束

如果这个帖子对你有所帮助,欢迎 关注 、点赞 、留言

end

相关文章:

C# 定时器封装版

一、概述 在 Winform 等平台开发中&#xff0c;经常会用到定时器的功能&#xff0c;但项目定时器一旦写多了&#xff0c;容易使软件变卡&#xff0c;而且运行时间长了会造成软件的闪退&#xff0c;这个可能是内存溢出造成的&#xff0c;具体原因我也没去深究&#xff0c;另一个…...

前端学习——Vue (Day4)

组件的三大组成部分 组件的样式冲突 scoped <template><div class"base-one">BaseOne</div> </template><script> export default {} </script><style scoped> /* 1.style中的样式 默认是作用到全局的2.加上scoped可以让样…...

如果你是一个嵌入式面试官,你会问哪些问题?

以下是一些嵌入式面试中可能会问到的问题&#xff1a; 1.你对嵌入式系统有什么理解&#xff1f;它们与桌面或服务器系统有什么不同&#xff1f; 2.你用过哪些单片机和微处理器&#xff1f;对其中哪一款最熟悉&#xff1f; 3.你用什么编程语言编写嵌入式软件&#xff1f;你觉…...

学习笔记十三:云服务器通过Kubeadm安装k8s1.25,供后续试验用

Kubeadm安装k8s1.25 k8s环境规划&#xff1a;初始化安装k8s集群的实验环境先建生产环境服务器&#xff0c;后面可以通过生成镜像克隆node环境修改主机名配置yum源关闭防火墙关闭selinux配置时间同步配置主机 hosts 文件&#xff0c;相互之间通过主机名互相访问 **192.168.40.18…...

【Maven】Maven配置国内镜像

文章目录 1. 配置maven的settings.xml文件1.1. 先把镜像mirror配置好1.2. 再把仓库配置好 2. 在idea中引用3. 参考资料 网上配置maven国内镜像的文章很多&#xff0c;为什么选择我&#xff0c;原因是&#xff1a;一次配置得永生、仓库覆盖广、仓库覆盖全面、作者自用的配置。 1…...

ChatGPT有几个版本,哪个版本最强,如何选择适合自己的?

​ChatGPT就像内容生产界的瑞士军刀。它可以是数学导师、治疗师、职业顾问、编程助手&#xff0c;甚至是旅行指南。只要你知道如何让它做你想做的事&#xff0c;ChatGPT几乎可以提供你要的任何东西。 但重要的是&#xff0c;你知道哪个版本的ChatGPT最能满足你的需求吗&#x…...

pg_standby备库搭建

1.主库 1.1主库参数文件修改 -- 该路径也需要在从库创建 mkdir -p /postgresql/archive chown -R postgres.postgres /postgresql/archive-- 主库配置归档 wal_levelreplica archive_modeon archive_commandcp %p /postgresql/archive/%f restore_commandcp /postgresql/arch…...

RNNLSTM

文章目录 前言引言应用示例-槽填充(slot filling)-订票系统二、循环神经网络(RNN)三、Long Short-term Memory (LSTM)LSTM原理[总结](https://zhuanlan.zhihu.com/p/42717426)LSTM例子lstm的训练RNN不但可以N2NMany2One(输入是一个矢量序列,但输出只有一个矢量)Many2Ma…...

到底什么是前后端分离

目录 Web 应用的开发主要有两种模式&#xff1a; 前后端不分离 前后端分离 总结 Web 应用的开发主要有两种模式&#xff1a; 前后端不分离 前后端分离 理解它们的区别有助于我们进行对应产品的测试工作。 前后端不分离 在早期&#xff0c;Web 应用开发主要采用前后端不…...

【React】精选5题

第1题&#xff1a;简述下 React 的生命周期&#xff1f;每个生命周期都做了什么&#xff1f; React 组件的生命周期可以分为三个阶段&#xff1a;挂载阶段、更新阶段和卸载阶段。每个生命周期方法都有特定的目的和功能。 挂载阶段&#xff1a; constructor&#xff1a;组件的构…...

MUR2080CT- ASEMI二极管的特性和应用

编辑-Z 本文将详细介绍MUR2080CT二极管的特性和应用。首先&#xff0c;将介绍MUR2080CT二极管的基本结构和工作原理。然后&#xff0c;将探讨MUR2080CT二极管的特性&#xff0c;包括正向电压降、反向漏电流和反向恢复时间等。接下来&#xff0c;将介绍MUR2080CT二极管在电源、…...

安全测试国家标准解读——资源管理和内存管理

下面的系列文章主要围绕《GB/T 38674—2020 信息安全技术 应用软件安全编程指南》进行讲解&#xff0c;该标准是2020年4月28日&#xff0c;由国家市场监督管理总局、国家标准化管理委员会发布&#xff0c;2020年11月01日开始实施。我们对该标准中一些常见的漏洞进行了梳理&…...

3D元宇宙游戏,或许能引爆新的文娱消费增长点

从去年开始&#xff0c;在互联网上&#xff0c;一个名为【神念无界-源起山海】的元宇宙游戏项目火了。除了可以在游戏内体验独战、团队式作战等3D古风经典游戏场景和玩法&#xff0c;还有钓鱼增加能量、情侣姻缘一线牵&#xff0c;结婚等多元化逼真效果与玩法&#xff0c;这令很…...

(学习笔记-IP)IP基础知识

基本认识 IP在TCP/IP参考模型中处于第三层&#xff0c;也就是网络层。 网络层的主要作用是&#xff1a;实现主机与主机之间的通信&#xff0c;也叫点对点的通信。 网络层与数据链路层的关系&#xff1a; MAC的作用是实现直连的两个设备之间通信&#xff0c;而IP负责没有直连的…...

神经数据库:用于使用 ChatGPT 构建专用 AI 代理的下一代上下文检索系统 — (第 2/3 部分)

书接上回理解构建LLM驱动的聊天机器人时的向量数据库检索的局限性 - &#xff08;第1/3部分&#xff09;_阿尔法旺旺的博客-CSDN博客 其中我们强调了&#xff08;1&#xff09;嵌入生成&#xff0c;然后&#xff08;2&#xff09;使用近似近邻&#xff08;ANN&#xff09;搜索…...

一文6个概念从0到1带你成功入门自动化测试【0基础也能看懂系列】

自动化测试有以下几个概念&#xff1a; 单元测试集成测试E2E 测试快照测试测试覆盖率TDD 以及 BDD 等 简述 项目开发过程中会有几个经历。 版本发布上线之前&#xff0c;会有好几个小时甚至是更长时间对应用进行测试&#xff0c;这个过程非常枯燥而痛苦代码的复杂度达到了一…...

C++OpenCV(5):图像模糊操作(四种滤波方法)

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 &#x1f506; OpenCV项目地址及源代码&#xff1a;点击这里 文章目录 图像模糊操作均值滤波高斯滤波中值滤波双边滤波 图像模糊操作 关于图片的噪声&#xff1a;指的是图片中存在的不必要或者多余的干扰数…...

关于质数筛——数论

埃式筛法 #include <bits/stdc.h> using namespace std; bool vis[100000010]; //标记数组 int n; int main(){scanf("%d",&n);vis[0]vis[1]1;for(int i2;i*i<n;i){ //优化1 if(vis[i]!1){for(int ji*i;j<n;ji){ //优化2 vis[j]1; //0是质数&#…...

Spring Boot 应用程序生命周期扩展点妙用

文章目录 前言1. 应用程序生命周期扩展点2. 使用场景示例2.1 SpringApplicationRunListener2.2 ApplicationEnvironmentPreparedEvent2.3 ApplicationPreparedEvent2.4 ApplicationStartedEvent2.5 ApplicationReadyEvent2.6 ApplicationFailedEvent2.7 ApplicationRunner 3. 参…...

【Nodejs】操作mongodb数据库

1.简介 Mongoose是一个让我们可以通过Node来操作MongoDB的模块。Mongoose是一个对象文档模型(ODM)库,它对Node原生的MongoDB模块进行了进一步的优化封装&#xff0c;并提供了更多的功能。在大多数情况下&#xff0c;它被用来把结构化的模式应用到一个MongoDB集合&#xff0c;并…...

通义千问3-Reranker-0.6B性能调优:提升推理速度的3种方法

通义千问3-Reranker-0.6B性能调优&#xff1a;提升推理速度的3种方法 1. 引言 如果你正在使用通义千问3-Reranker-0.6B模型&#xff0c;可能会遇到推理速度不够理想的情况。特别是在处理大量文本排序任务时&#xff0c;等待时间可能会影响整体工作效率。 其实&#xff0c;这…...

Docker 部署 Vaultwarden:轻量级自托管密码管理解决方案

1. 为什么选择Vaultwarden作为自托管密码管理方案 在这个数字时代&#xff0c;我们每个人平均要管理超过100个在线账户的密码。传统的密码管理方式——用同一个简单密码注册所有网站&#xff0c;或者把密码写在记事本上——已经远远不能满足安全需求。这就是为什么像Bitwarden这…...

Java笔记——JMM

在多线程编程中&#xff0c;共享变量的可见性、操作的原子性以及指令的重排序&#xff0c;常常成为导致程序出现诡异Bug的罪魁祸首。而Java之所以能够成为并发编程的首选语言之一&#xff0c;很大程度上归功于其强大的Java内存模型&#xff08;Java Memory Model, JMM&#xff…...

进阶篇第5节:共享内存(三)——实战:优化矩阵乘法(Tiling技术)

第二篇进阶篇第5节:共享内存(三)——实战:优化矩阵乘法(Tiling技术) 从朴素到分块,从分块到极致——矩阵乘法的优化之路,就是CUDA性能优化的缩影 写在前面 矩阵乘法是CUDA优化中最经典的案例,没有之一。在筑基篇,我们实现了朴素版本和基础分块版本,性能从 252 GFLO…...

ISIS实验1

ISIS实验1网络拓扑配置一、AR1二、AR2三、测试1. 查看 IS-IS 邻居状态2. 查看 IS-IS 接口信息3. 查看 IS-IS 路由表4. 查看 IP 路由表中的 IS-IS 路由5. 查看链路状态数据库&#xff08;LSDB&#xff09;6. 检查&#xff1a;Level-1 区域一致性四、AR3五、AR4六、检测1. 通过链…...

喜马拉雅FM专辑下载器:离线收听与个人音频管理的实用方案

喜马拉雅FM专辑下载器&#xff1a;离线收听与个人音频管理的实用方案 【免费下载链接】xmly-downloader-qt5 喜马拉雅FM专辑下载器. 支持VIP与付费专辑. 使用GoQt5编写(Not Qt Binding). 项目地址: https://gitcode.com/gh_mirrors/xm/xmly-downloader-qt5 如果您经常收…...

解锁新可能:ArkData 在智能穿戴设备中的应用

解锁新可能&#xff1a;ArkData 在智能穿戴设备中的应用随着人们对健康生活的重视&#xff0c;智能穿戴设备愈发普及。这些设备能够实时收集心率、步数、睡眠等健康数据&#xff0c;为人们的健康管理提供重要参考。在这一背景下&#xff0c;如何高效管理和利用这些健康数据成为…...

el-tabs报错Cannot read properties of null (reading ‘insertBefore‘)

使用elementui-plus的tabs组件在开发中遇到的一个问题&#xff0c;分析了代码&#xff0c;发现逻辑没有任何问题&#xff0c;但是点击tab切换就会报错&#xff1a;Uncaught (in promise) TypeError: Cannot read properties of null (reading insertBefore)调试发现parent参数是…...

Skytraq NavIC库:Arduino平台的GNSS驱动与区域增强开发指南

1. Skytraq NavIC 库概述Skytraq NavIC 库是一个面向 Arduino 平台的完整 GNSS 驱动框架&#xff0c;专为基于 Skytraq 芯片组&#xff08;如 SGR-03、SGR-05、SGR-07 系列&#xff09;的高精度定位模块设计。该库不仅全面支持全球主流卫星导航系统&#xff0c;更深度适配印度区…...

OpenClaw日志分析:QwQ-32B任务执行效率监控

OpenClaw日志分析&#xff1a;QwQ-32B任务执行效率监控 1. 为什么需要监控OpenClaw任务执行效率 去年冬天&#xff0c;我部署了一个自动整理会议纪要的OpenClaw工作流。起初运行得很顺利&#xff0c;直到某天早上发现它漏掉了三场重要会议的记录。检查日志才发现&#xff0c;…...