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

c# 后台任务自动执行

如果有些任务需要在后台自动执行,且时不时需要添加一个任务,且按照优先级顺序执行,那么可以参考本文的方法。

后台任务类

定义一个后台任务类BackgroundTaskThread,其中Start方法是用来启动任务的,循环查询是否有添加任务,外部一般就调用AppendTask来添加任务。循环任务发现任务有添加后,会自动执行。如果有多个任务,会按加入的顺序一个一个执行。

public class BackgroundTaskThread
{/// <summary>/// 任务列表/// </summary>private List<TaskItem> TaskItems = new List<TaskItem>();/// <summary>/// 等待时间/// </summary>public int MillSeconds = 1000;/// <summary>/// 自动重置/// </summary>public AutoResetEvent TaskSet = new AutoResetEvent(false);/// <summary>/// 任务取消标识/// </summary>public CancellationTokenSource Source { get; set; } = new CancellationTokenSource();/// <summary>/// 日志/// </summary>public ILog Log { get; set; }/// <summary>/// 线程数量/// </summary>public int ThreadNum { get; private set; }/// <summary>/// 任务线程/// </summary>public List<Task> TaskThreads = new List<Task>();/// <summary>/// 启动/// </summary>/// <param name="taskTimeSpan">任务扫描间隔</param>/// <param name="taskNum">任务数量</param>public void Start(int taskTimeSpan, int taskNum){ThreadNum = taskNum;for (int i = 0; i < taskNum; i++){MillSeconds = taskTimeSpan;Task task = new Task(BackgroundThread);task.Start();TaskThreads.Add(task);}}/// <summary>/// 后台任务/// </summary>private void BackgroundThread(){try{while (!Source.Token.IsCancellationRequested){var item = GetOrSetTaskItem(true, null);if(item == null){TaskSet.WaitOne(MillSeconds);}else{try{item.Task.Invoke(item.Param);}catch (Exception ex){Log.error("任务 : ", item.Name, " 异常停止.,..", ex);}}}}catch (Exception ex){Log.error("后台任务线程异常退出....", ex);}}/// <summary>/// 读取或者/// </summary>/// <param name="isGet">是否是获取</param>/// <param name="item">任务项</param>/// <returns></returns>protected TaskItem GetOrSetTaskItem(bool isGet, TaskItem item){lock (this){if (isGet){if (TaskItems.Count == 0)return null;item = TaskItems[0];TaskItems.RemoveAt(0);return item;}else{TaskItems.Add(item);return item;}}}/// <summary>/// 追加任务/// </summary>/// <param name="task"></param>/// <param name="param"></param>public void AppendTask(Action<object> task, object param){GetOrSetTaskItem(false, new TaskItem() { Task = task, Param = param });TaskSet.Set();}/// <summary>/// 释放/// </summary>public void Dispose(){if(TaskThreads.Count > 0)Source.Cancel();TaskItems.Clear();}
}

内部任务定义类

public class TaskItem
{/// <summary>/// 任务/// </summary>public Action<object> Task { get; set; }/// <summary>/// 参数/// </summary>public object Param { get; set; }/// <summary>/// 任务名称/// </summary>public string Name { get; set; } = string.Empty;
}

实际任务

public class DoSomethingTaskThread : BackgroundTaskThread
{public void AppendSomething(object data){AppendTask(DoSomething, data);}private void DoSomething(object data){//TODO}
}

外部调用

当然,最好把DoSomethingTaskThread这个子类做成单例,后面直接

//启动任务,同步的话线程数传1,异步的话线程数可以传多点
DoSomethingTaskThread.Start(1000,1);//添加任务
DoSomethingTaskThread.AppendSomething(new object());
http://www.lryc.cn/news/509140.html

相关文章:

  • 被裁20240927 --- 嵌入式硬件开发 前篇
  • 重温设计模式--观察者模式
  • vulnhub靶场——Log4j2
  • Vue3中使用resolve进行路径别名设置
  • Linux 添加磁盘
  • 集成 jacoco 插件,查看单元测试覆盖率
  • MySQL purged gtid是如何生成和维护的
  • [创业之路-206]:《华为战略管理法-DSTE实战体系》- 6-关键成功因素法CSF
  • [Unity]【图形渲染】【游戏开发】Shader数学基础4-更多矢量运算
  • 目标检测——基于yolov8和pyqt的螺栓松动检测系统
  • 【Java数据结构】LinkedList
  • 图像处理-Ch4-频率域处理
  • WPS工具栏灰色怎么办
  • 渐开线齿轮和摆线齿轮有什么区别?
  • vulnhub靶场-matrix-breakout-2-morpheus攻略(截止至获取shell)
  • 应用高次、有理代数式为AI生成亚对称图像
  • 潜在狄利克雷分配LDA 算法深度解析
  • [x86 ubuntu22.04]双触摸屏的触摸事件都响应在同一个触摸屏上
  • 重温设计模式--代理模式
  • 一些elasticsearch重要概念与配置参数
  • leetcode 面试经典 150 题:螺旋矩阵
  • JAVA AOP简单实践(基于SpringBoot)
  • java agent的使用【通俗易懂版】
  • 大模型学习指南
  • 单片机:实现定时器中断(数码管读秒+LED闪烁)(附带源码)
  • STM32单片机芯片与内部33 ADC 单通道连续DMA
  • 【0376】Postgres内核 分配 last safe MultiXactId
  • php时间strtotime函数引发的问题 时间判断出错
  • Kibana:LINUX_X86_64 和 DEB_X86_64两种可选下载方式的区别
  • 【LeetCode每日一题】 LeetCode 151.反转字符串中的单词