C#:用定时器监控定时器,实现中止定时器正在执行的任务,并重启

news2024/11/26 9:47:57

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或1
                if (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或1
                if (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);
            }
        }
    }
}

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

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

相关文章

DataX,MongoDB数据导入hdfs与mysql

【尚硅谷】Alibaba开源数据同步工具DataX技术教程【尚硅谷】Alibaba开源数据同步工具DataX技术教程_哔哩哔哩_bilibili 目录 1、MongoDB 1.1、MongoDB介绍 1.2、MongoDB基本概念解析 1.3、MongoDB中的数据存储结构 1.4、MongoDB启动服务 1.5、MongoDB小案例 2、DataX导入…

vmware 一打开虚拟机就蓝屏重启

按照正常步骤安装完镜像后&#xff0c;点击 开启此虚拟机 &#xff0c;直接出现下图所示蓝屏&#xff0c;然后重启。 解决的办法是通过修改 启用或关闭windows功能 里的选项&#xff0c;如下图&#xff0c;勾选上 Windows虚拟机监控程序平台 和 虚拟机平台 两项。然后重启电脑…

C语言之自定义类型联合和枚举

目录 前言 一&#xff1a;联合体&#xff08;共用体&#xff09;union 1.联合体类型的声明 2.联合体的特点 3.联合体大小的计算 4.联合体判断机器的大小端 二&#xff1a;枚举enum 1.概念 2.枚举的优点 3.枚举的使用 接下来的日子会顺顺利利&#xff0c;万事胜意…

[paper note]LoRA+: 原理分析

论文信息 论文标题&#xff1a;LoRA: Efficient Low Rank Adaptation of Large Models 发表时间&#xff1a;2024年2月 论文内容 摘要 在本文中&#xff0c;我们表明&#xff0c;最初在论文《LoRA: Low-Rank Adaptation of Large Language Models》中引入的低秩适应&#…

人工智能应用工程师特训营丨国家认证,行业必备

人工智能应用工程特训营 提升目标&#xff1a; 1、提高专业认可度&#xff0c;增强职场竞争力 2、实战项目驱动&#xff0c;提升应用能力 3、技术体系全面&#xff0c;涵盖多个领域 4、实时在线答疑&#xff0c;强化学习互动 特训营学习流程&#xff1a; 职业技术证书&#xff…

WinRAR功能之【锁定压缩文件】

今天来分享一下WinRAR解压缩软件的“锁定压缩文件”功能&#xff0c;这个功能可以保护压缩包里文件的完整性&#xff0c;也就是不能随意增加、删除以及修改压缩包里的文件。我们可以用两种方式来设置&#xff0c;一起来看看吧&#xff01; 方式1&#xff1a;在压缩文件的时候&a…

Matlab进阶绘图第49期—气泡堆叠图

气泡堆叠图是堆叠图与气泡图的组合—在堆叠图每根柱子上方添加大小不同的气泡&#xff0c;用于表示另外一个数据变量&#xff08;如每根柱子各组分的平均值&#xff09;的大小。 本文利用自己制作的BarBubble工具&#xff0c;进行气泡堆叠图的绘制&#xff0c;先来看一下成品效…

牛客 2024春招冲刺题单 ONT82 腐烂的苹果【中等 BFS Java,Go】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/54ab9865ce7a45968b126d6968a77f34 思路 广度优先搜索。首先找到2坐标集合&#xff0c;然后每次往四周为1的坐标扩展参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数…

Unity 世界坐标、屏幕坐标、UGUI 坐标 相互转换

Unity 世界坐标、屏幕坐标、UGUI 坐标 相互转换坐标转换是游戏开发过程中必不可少的环节 看下图 世界坐标、屏幕坐标、UI 坐标 三种坐标系的转换过程&#xff0c;此文章中的 UI 坐标特指 UGUI 坐标 从上图可以看到&#xff0c;世界坐标 和 UI 坐标 需要通过 屏幕坐标作为中间转…

从“危”到“机”:HubSpot如何助企业转化出海营销CRM风险?

在全球化的大背景下&#xff0c;越来越多的企业选择出海拓展业务&#xff0c;以寻求更大的发展空间。然而&#xff0c;随着市场的扩大&#xff0c;企业在出海营销过程中也面临着各种风险。为了有效规避这些风险&#xff0c;许多企业选择借助HubSpot这样的专业营销软件。今天运营…

A Study of Network Forensic Investgation in Docker Environments文章翻译

A Study of Network Forensic Investgation in Docker Environments Docker环境下的网络取证研究 摘要 网络罪犯利用越来越多的技术(如虚拟机或基于容器的基础设施)进行恶意活动。 这些虚拟环境的固有动态简化了恶意服务的快速创建,并隐藏了所涉及的系统,这是以前没有的技…

C语言面试题之化栈为队

化栈为队 实例要求 C语言实现实现一个MyQueue类&#xff0c;该类用两个栈来实现一个队列&#xff1b;示例&#xff1a; MyQueue queue new MyQueue();queue.push(1); queue.push(2); queue.peek(); // 返回 1 queue.pop(); // 返回 1 queue.empty(); // 返回 false说明&…

关于51单片机TMOD定时器的安全配置

定时器介绍&#xff1a; -------------------------------------------------------------------------------------------------------------------------- 首先配置的是控制寄存器 TCON 说直白点&#xff0c;这个寄存器就是用来计数的&#xff0c;打开计时器&#xff0c;关…

UEditor 任意文件上传漏洞

前言 前段时间在做某政府单位的项目的时候发现存在该漏洞&#xff0c;虽然是一个老洞&#xff0c;但这也是容易被忽视&#xff0c;且能快速拿到shell的漏洞&#xff0c;在利用方式上有一些不一样的心得&#xff0c;希望能帮助到一些还不太了解的小伙伴&#xff0c;故此写了此篇…

AI爆款文案 巧用AI大模型让文案变现插上翅膀

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

kali基础渗透学习,永恒之蓝,木马实战

简介 kali的学习本质是在linux上对一些攻击软件的使用&#xff0c;只是学习的初期 先在终端切换到root用户&#xff0c;以便于有些工具对权限的要求 下载链接 镜像源kali 攻击流程 公网信息搜集 寻找漏洞&#xff0c;突破口&#xff0c;以进入内网 进入内网&#xff0c…

组装机械狗电子玩具方案

这款机械狗玩具电子方案结合了现代电子技术和人工智能元素&#xff0c;旨在为用户提供一个高科技、互动性强的娱乐体验。通过不断的软件更新和硬件迭代&#xff0c;机械狗的功能将持续扩展。 一、功能特点&#xff1a; 1、自动巡游&#xff1a;机械狗能够自主在房间内巡游&am…

用Wireshark工具对gRPC接口进行本地抓包

前言&#xff1a; 本人一名敲代码的程序员&#xff0c;突然领导安排研究gRPC接口&#xff0c;并且抓包分析&#xff0c; 抓包工具试了Charles、mitmproxy都不行&#xff0c;浪费很多时间&#xff0c;最后使用Wireshark工具对本地启动的gRPC接口成功抓包&#xff0c;关于安装W…

modelsim 仿真bmp图片实现RGB_YCrCb

用modelsim_se软件仿真bmp图片&#xff0c;可在modesim中实现一些图片处理算法和查看效果 本文以最简单的仿真一副bmp图像为例&#xff0c;实现RGB_YCrCb的modelsim仿真,带源工程 1、先在本地建立文件夹 2、首先打开moselsim 3、新建库和新建项目&#xff0c;保存到建立的文件…

逐行讲解python实现A*路径规划

目录 搜索步骤关键点开集合和闭集合复杂度优化 代价父节点替换 距离地图设置 完整代码备注 搜索步骤 A*路径规划是一种广度优先搜索算法&#xff0c;需要在栅格地图上进行搜索。其主要搜索步骤如下&#xff1a; 得到栅格地图&#xff0c;确定起点和终点位置&#xff1b;计算起…