C#:用定时器监控定时器,实现中止定时器正在执行的任务,并重启
Windows服务中使用的比较多的是定时器,但这种定时任务有个比较大的毛病:有时会莫名其妙地停止执行(长时间执行不完,假死),必须得手工重启Windows服务才能恢复正常。这个就太麻烦了。
有没有办法来实现定时器出现问题时自动重启定时器呢?我们做个小实验:
一、能否用Stop来中止定时器正在执行的任务?不行。
using System;
using System.Timers;namespace TestTimer
{internal class Program{private static int usingResource = 0;static int m = 0;static Timer timerTask = new Timer();static Timer timerMonitor = new Timer();static void Main(string[] args){//任务 定时器timerTask.AutoReset = true;timerTask.Interval = 1 * 1000;//1秒触发一次timerTask.Enabled = true;timerTask.Elapsed += TimerTask_Elapsed;timerTask.Start();//监控 定时器timerMonitor.AutoReset = true;timerMonitor.Interval = 1 * 1000;//1秒触发一次timerMonitor.Enabled = true;timerMonitor.Elapsed += TimerMonitor_Elapsed; ;timerMonitor.Start();Console.Read();}private static void TimerMonitor_Elapsed(object sender, ElapsedEventArgs e){Console.WriteLine("m={0}", m);if (m == 1){Console.WriteLine("set task stop");timerTask.Stop();}}private static void TimerTask_Elapsed(object sender, ElapsedEventArgs e){if (0 == System.Threading.Interlocked.Exchange(ref usingResource, 1)){m = new Random().Next(0, 2);//m只可能为0或1if (m == 0)Console.WriteLine("m=0 => {0:HH:mm:ss}", DateTime.Now);else{for (int i = 0; i < 999999999; i++){Console.WriteLine("m=1 => {0:HH:mm:ss}", DateTime.Now);System.Threading.Thread.Sleep(1000);}}System.Threading.Interlocked.Exchange(ref usingResource, 0);}else{Console.WriteLine("{0:yyyy-MM-dd HH:mm:ss}, 未取得锁,已退出", DateTime.Now);}}}
}
由上面代码可以得到下面的结果:
没有停止。

===================== 华丽的分隔线 =====================
二、直接中止线程来中止执行,并重启定时器:可以
下面的代码成功实现了用定时器TimerMonitor监控定时器TimerTask,如果有问题则立即中止TimerTask的线程,并实现重启TimerTask定时器的功能。
using System;
using System.Threading;
using System.Timers;
using Timer = System.Timers.Timer;namespace TestTimer
{internal class Program{private static int usingResourceTask = 0;private static int usingResourceMonitor = 0;static int m = 0;static Timer timerTask = new Timer();static Timer timerMonitor = new Timer();static Thread taskThread = null;static void Main(string[] args){//任务 定时器timerTask.AutoReset = true;timerTask.Interval = 2 * 1000;//2秒触发一次timerTask.Enabled = true;timerTask.Elapsed += TimerTask_Elapsed;timerTask.Start();//监控 定时器timerMonitor.AutoReset = true;timerMonitor.Interval = 2 * 1000;//2秒触发一次timerMonitor.Enabled = true;timerMonitor.Elapsed += TimerMonitor_Elapsed; ;timerMonitor.Start();Console.Read();}private static void TimerMonitor_Elapsed(object sender, ElapsedEventArgs e){if (0 == System.Threading.Interlocked.Exchange(ref usingResourceMonitor, 1)){Console.WriteLine("TimerMonitor {0}=> m={1}", DateTime.Now.ToString("HH:mm:ss"), m);if (m == 1)//用这个模拟出现了异常现象{m = 0; //避免后一次快速进入Console.WriteLine("TimerMonitor {0}=> 即将中止 timerTask 线程 ", DateTime.Now.ToString("HH:mm:ss"));taskThread.Abort();Console.WriteLine("TimerMonitor {0}=> 已将 timerTask 执行停止", DateTime.Now.ToString("HH:mm:ss"));Thread.Sleep(10 * 1000);//暂停10秒,再重启定时器timerTask.Stop();Console.WriteLine("TimerMonitor {0}=> Task定时器在中止后10秒已设置为停止状态", DateTime.Now.ToString("HH:mm:ss"));//将任务的锁释放System.Threading.Interlocked.Exchange(ref usingResourceTask, 0);timerTask.Start();Console.WriteLine("TimerMonitor {0}=> Task定时器已设置为开启", DateTime.Now.ToString("HH:mm:ss"));}System.Threading.Interlocked.Exchange(ref usingResourceMonitor, 0);}else{//Console.WriteLine("TimerMonitor {0:yyyy-MM-dd HH:mm:ss}, 未取得锁,已退出", DateTime.Now);}}private static void TimerTask_Elapsed(object sender, ElapsedEventArgs e){taskThread = Thread.CurrentThread;if (0 == System.Threading.Interlocked.Exchange(ref usingResourceTask, 1)){m = new Random().Next(0, 2);//m只可能为0或1if (m == 0)Console.WriteLine("TimerTask m=0 => {0:HH:mm:ss}", DateTime.Now);else{for (int i = 0; i < 999999999; i++){Console.WriteLine("TimerTask m=1 => {0:HH:mm:ss}", DateTime.Now);System.Threading.Thread.Sleep(1000);}}System.Threading.Interlocked.Exchange(ref usingResourceTask, 0);}else{//Console.WriteLine("TimerTask {0:yyyy-MM-dd HH:mm:ss}, 未取得锁,已退出", DateTime.Now);}}}
}

相关文章:
C#:用定时器监控定时器,实现中止定时器正在执行的任务,并重启
Windows服务中使用的比较多的是定时器,但这种定时任务有个比较大的毛病:有时会莫名其妙地停止执行(长时间执行不完,假死),必须得手工重启Windows服务才能恢复正常。这个就太麻烦了。 有没有办法来实现定时…...
计算机组成原理 — CPU 的结构和功能
CPU 的结构和功能 CPU 的结构和功能CPU 概述控制器概述CPU 框架图CPU 寄存器控制单元 CU 指令周期概述指令周期的数据流 指令流水概述指令流水的原理影响流水线性能的因素流水线的性能流水线的多发技术流水线结构 中断系统概述中断请求标记和中断判优逻辑中断请求标记 INTR中断…...
npm包安装与管理:深入解析命令行工具的全方位操作指南,涵盖脚本执行与包发布流程
npm,全称为Node Package Manager,是专为JavaScript生态系统设计的软件包管理系统,尤其与Node.js平台紧密关联。作为Node.js的默认包管理工具,npm为开发者提供了便捷的方式来安装、共享、分发和管理代码模块。 npm作为JavaScript世…...
序列化结构(protobuf)实现一个TCP服务器(C++)
Protocol Buffers(protobuf)是一种由Google开发的用于序列化结构化数据的方法,通常用于在不同应用程序之间进行数据交换或存储数据。它是一种语言无关、平台无关、可扩展的机制,可以用于各种编程语言和环境中。 1、首先建立proto文…...
Python中的list()和map() 用法
list() 在Python中,list() 是一个内置函数,用于创建列表(list)对象。它有几个不同的用途,但最常见的是将一个可迭代对象(如元组、字符串、集合或其他列表)转换为一个新的列表。 以下是一些使用…...
公网环境下如何端口映射?
公网端口映射是一种网络技术,它允许将本地网络中的设备暴露在公共互联网上,以便能够从任何地方访问这些设备。通过公网端口映射,用户可以通过互联网直接访问和控制局域网中的设备,而无需在本地网络中进行复杂的配置。 公网端口映射…...
7-36 输入年份和月份
输入一个年份和月份,输出这个月的天数。 输入格式: 输入年份year和月份month,年份和月份中间用一个空格隔开。 输出格式: 输入year年的month月对应的天数。 输入样例: 2000 2输出样例: 29输入样例: 1900 2输出样例: 28输入样例: 1900 6输出样例…...
Linux C++ 023-类模板
Linux C 023-类模板 本节关键字:Linux、C、类模板 相关库函数:getCapacity、getSize 类模板语法 类模板的作用:建立一个通用的类,类中的成员 数据类型可以不具体制定, 用一个虚拟的类型代表语法: templa…...
Android图形显示架构概览
图形显示系统作为Android系统核心的子系统,掌握它对于理解Android系统很有帮助,下面从整体上简单介绍图形显示系统的架构,如下图所示。 这个框架只包含了用户空间的图形组件,不涉及底层的显示驱动。框架主要包括以下4个图形组件。…...
算法学习17:背包问题(动态规划)
算法学习17:背包问题(动态规划) 文章目录 算法学习17:背包问题(动态规划)前言一、01背包问题:1.朴素版:(二维)2.优化版:(一维…...
axios-mock-adapter使用
文章目录 1. 安装 axios-mock-adapter2. 引入所需的库3. 创建一个模拟适配器实例4. 定义模拟响应5. 在你的代码中使用 axios6. 在测试或开发完成后清理模拟 axios-mock-adapter 是一个用于模拟 axios HTTP 请求的库。它允许你在测试或开发过程中,为 axios 实例提供…...
基于单片机的家用无线火灾报警系统设计
摘 要:针对普通家庭的火灾防范需求,设计一种基于单片机的家用无线智能火灾报警系统。该系统主要由传感器、单片机、无线通信模块、GSM 模块、输入显示模块、声光报警电路和GSM 报警电路组成。系统工作时,检测部分单片机判断是否发生火灾,并将信息通过无线通信模块传…...
LangChain:索引(Indexes)--基础知识
引言 在当今信息爆炸的时代,如何高效地获取、处理和利用信息成为了关键。LangChain,作为一种先进的语言模型框架,提供了强大的索引功能,帮助用户更好地管理和应用文本数据。本文将详细介绍LangChain索引中的几个核心组件…...
Cortex-M4架构
第一章 嵌入式系统概论 1.1 嵌入式系统概念 用于控制、监视或者辅助操作机器和设备的装置,是一种专用计算机系统。 更宽泛的定义:是在产品内部,具有特定功能的计算机系统。 1.2 嵌入式系统组成 硬件 ①处理器:CPU ②存储器…...
对称排序(蓝桥杯)
文章目录 对称排序问题描述模拟 对称排序 问题描述 小蓝是一名软件工程师,他正在研究一种基于交换的排序算法,以提高排序的效率。 给定一个长度为 N 的数组 A,小蓝希望通过交换对称元素的方式对该数组进行排序。 具体来说,小蓝…...
React - 你使用过高阶组件吗
难度级别:初级及以上 提问概率:55% 高阶组件并不能单纯的说它是一个函数,或是一个组件,在React中,函数也可以做为一种组件。而高阶组件就是将一个组件做为入参,被传入一个函数或者组件中,经过一定的加工处理,最终再返回一个组件的组合…...
【C语言】结构体、枚举、联合(自定义类型)
文章目录 前言一、结构体1.结构体的声明2.结构体的自引用3.结构体变量的定义和初始化4.结构体成员的访问5.结构体内存对齐(重点)6.#pragma修改默认对齐数7.结构体传参 二、位段1.位段的声明2.位段的内存分配3.位段的跨平台问题 三、枚举四、联合 &#x…...
用vue.js写案例——ToDoList待办事项 (步骤和全码解析)
目录 一.准备工作 二.编写各个组件的页面结构 三.实现初始任务列表的渲染 四.新增任务 五.删除任务 六.展示未完成条数 七.切换状态-筛选数据 八.待办事项(全)代码 一.准备工作 在开发“ToDoList”案例之前,需要先完成一些准备工作&a…...
提高大型语言模型 (LLM) 性能的四种数据清理技术
原文地址:four-data-cleaning-techniques-to-improve-large-language-model-llm-performance 2024 年 4 月 2 日 检索增强生成(RAG)过程因其增强对大语言模型(LLM)的理解、为它们提供上下文并帮助防止幻觉的潜力而受…...
Rust 练手小项目:猜数游戏
好久没写 Rust 了,参考《Rust 程序设计语言》写了一下猜数游戏。差不多 40 行,感觉写起来真舒服。 use rand::Rng; use std::{cmp::Ordering, io};fn main() {let secret_number rand::thread_rng().gen_range(0..100);println!("[*] Guess the n…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
