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

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服务中使用的比较多的是定时器&#xff0c;但这种定时任务有个比较大的毛病&#xff1a;有时会莫名其妙地停止执行&#xff08;长时间执行不完&#xff0c;假死&#xff09;&#xff0c;必须得手工重启Windows服务才能恢复正常。这个就太麻烦了。 有没有办法来实现定时…...

计算机组成原理 — CPU 的结构和功能

CPU 的结构和功能 CPU 的结构和功能CPU 概述控制器概述CPU 框架图CPU 寄存器控制单元 CU 指令周期概述指令周期的数据流 指令流水概述指令流水的原理影响流水线性能的因素流水线的性能流水线的多发技术流水线结构 中断系统概述中断请求标记和中断判优逻辑中断请求标记 INTR中断…...

npm包安装与管理:深入解析命令行工具的全方位操作指南,涵盖脚本执行与包发布流程

npm&#xff0c;全称为Node Package Manager&#xff0c;是专为JavaScript生态系统设计的软件包管理系统&#xff0c;尤其与Node.js平台紧密关联。作为Node.js的默认包管理工具&#xff0c;npm为开发者提供了便捷的方式来安装、共享、分发和管理代码模块。 npm作为JavaScript世…...

序列化结构(protobuf)实现一个TCP服务器(C++)

Protocol Buffers&#xff08;protobuf&#xff09;是一种由Google开发的用于序列化结构化数据的方法&#xff0c;通常用于在不同应用程序之间进行数据交换或存储数据。它是一种语言无关、平台无关、可扩展的机制&#xff0c;可以用于各种编程语言和环境中。 1、首先建立proto文…...

Python中的list()和map() 用法

list() 在Python中&#xff0c;list() 是一个内置函数&#xff0c;用于创建列表&#xff08;list&#xff09;对象。它有几个不同的用途&#xff0c;但最常见的是将一个可迭代对象&#xff08;如元组、字符串、集合或其他列表&#xff09;转换为一个新的列表。 以下是一些使用…...

公网环境下如何端口映射?

公网端口映射是一种网络技术&#xff0c;它允许将本地网络中的设备暴露在公共互联网上&#xff0c;以便能够从任何地方访问这些设备。通过公网端口映射&#xff0c;用户可以通过互联网直接访问和控制局域网中的设备&#xff0c;而无需在本地网络中进行复杂的配置。 公网端口映射…...

7-36 输入年份和月份

输入一个年份和月份&#xff0c;输出这个月的天数。 输入格式: 输入年份year和月份month&#xff0c;年份和月份中间用一个空格隔开。 输出格式: 输入year年的month月对应的天数。 输入样例: 2000 2输出样例: 29输入样例: 1900 2输出样例: 28输入样例: 1900 6输出样例…...

Linux C++ 023-类模板

Linux C 023-类模板 本节关键字&#xff1a;Linux、C、类模板 相关库函数&#xff1a;getCapacity、getSize 类模板语法 类模板的作用&#xff1a;建立一个通用的类&#xff0c;类中的成员 数据类型可以不具体制定&#xff0c; 用一个虚拟的类型代表语法&#xff1a; templa…...

Android图形显示架构概览

图形显示系统作为Android系统核心的子系统&#xff0c;掌握它对于理解Android系统很有帮助&#xff0c;下面从整体上简单介绍图形显示系统的架构&#xff0c;如下图所示。 这个框架只包含了用户空间的图形组件&#xff0c;不涉及底层的显示驱动。框架主要包括以下4个图形组件。…...

算法学习17:背包问题(动态规划)

算法学习17&#xff1a;背包问题&#xff08;动态规划&#xff09; 文章目录 算法学习17&#xff1a;背包问题&#xff08;动态规划&#xff09;前言一、01背包问题&#xff1a;1.朴素版&#xff1a;&#xff08;二维&#xff09;2.优化版&#xff1a;&#xff08;一维&#xf…...

axios-mock-adapter使用

文章目录 1. 安装 axios-mock-adapter2. 引入所需的库3. 创建一个模拟适配器实例4. 定义模拟响应5. 在你的代码中使用 axios6. 在测试或开发完成后清理模拟 axios-mock-adapter 是一个用于模拟 axios HTTP 请求的库。它允许你在测试或开发过程中&#xff0c;为 axios 实例提供…...

基于单片机的家用无线火灾报警系统设计

摘 要:针对普通家庭的火灾防范需求,设计一种基于单片机的家用无线智能火灾报警系统。该系统主要由传感器、单片机、无线通信模块、GSM 模块、输入显示模块、声光报警电路和GSM 报警电路组成。系统工作时,检测部分单片机判断是否发生火灾,并将信息通过无线通信模块传…...

LangChain:索引(Indexes)--基础知识

引言 在当今信息爆炸的时代&#xff0c;如何高效地获取、处理和利用信息成为了关键。LangChain&#xff0c;作为一种先进的语言模型框架&#xff0c;提供了强大的索引功能&#xff0c;帮助用户更好地管理和应用文本数据。本文将详细介绍LangChain索引中的几个核心组件&#xf…...

Cortex-M4架构

第一章 嵌入式系统概论 1.1 嵌入式系统概念 用于控制、监视或者辅助操作机器和设备的装置&#xff0c;是一种专用计算机系统。 更宽泛的定义&#xff1a;是在产品内部&#xff0c;具有特定功能的计算机系统。 1.2 嵌入式系统组成 硬件 ①处理器&#xff1a;CPU ②存储器…...

对称排序(蓝桥杯)

文章目录 对称排序问题描述模拟 对称排序 问题描述 小蓝是一名软件工程师&#xff0c;他正在研究一种基于交换的排序算法&#xff0c;以提高排序的效率。 给定一个长度为 N 的数组 A&#xff0c;小蓝希望通过交换对称元素的方式对该数组进行排序。 具体来说&#xff0c;小蓝…...

React - 你使用过高阶组件吗

难度级别:初级及以上 提问概率:55% 高阶组件并不能单纯的说它是一个函数,或是一个组件,在React中,函数也可以做为一种组件。而高阶组件就是将一个组件做为入参,被传入一个函数或者组件中,经过一定的加工处理,最终再返回一个组件的组合…...

【C语言】结构体、枚举、联合(自定义类型)

文章目录 前言一、结构体1.结构体的声明2.结构体的自引用3.结构体变量的定义和初始化4.结构体成员的访问5.结构体内存对齐&#xff08;重点&#xff09;6.#pragma修改默认对齐数7.结构体传参 二、位段1.位段的声明2.位段的内存分配3.位段的跨平台问题 三、枚举四、联合 &#x…...

用vue.js写案例——ToDoList待办事项 (步骤和全码解析)

目录 一.准备工作 二.编写各个组件的页面结构 三.实现初始任务列表的渲染 四.新增任务 五.删除任务 六.展示未完成条数 七.切换状态-筛选数据 八.待办事项&#xff08;全&#xff09;代码 一.准备工作 在开发“ToDoList”案例之前&#xff0c;需要先完成一些准备工作&a…...

提高大型语言模型 (LLM) 性能的四种数据清理技术

原文地址&#xff1a;four-data-cleaning-techniques-to-improve-large-language-model-llm-performance 2024 年 4 月 2 日 检索增强生成&#xff08;RAG&#xff09;过程因其增强对大语言模型&#xff08;LLM&#xff09;的理解、为它们提供上下文并帮助防止幻觉的潜力而受…...

Rust 练手小项目:猜数游戏

好久没写 Rust 了&#xff0c;参考《Rust 程序设计语言》写了一下猜数游戏。差不多 40 行&#xff0c;感觉写起来真舒服。 use rand::Rng; use std::{cmp::Ordering, io};fn main() {let secret_number rand::thread_rng().gen_range(0..100);println!("[*] Guess the n…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...