浅谈C#之任务调度TaskScheduler
一、基本介绍
TaskScheduler
是一个抽象类,用于控制任务的执行方式,特别是它们如何被安排到线程池中的线程上执行。
TaskScheduler
负责将 Task
对象排队并决定何时、以何种方式执行这些任务。
二、TaskScheduler的作用
调度任务:将任务分配给线程池中的线程执行。
控制并发:通过限制同时执行的任务数量来控制并发级别。
异常处理:虽然不是直接由 TaskScheduler
处理异常,但它通过控制任务的执行环境间接影响了异常的处理方式。
三、TaskScheduler的关键点
默认调度器:大多数情况下,任务默认在 TaskScheduler.Default
调度器上运行,它通常与线程池中的线程关联。
自定义调度器:你可以创建自定义的 TaskScheduler
来控制任务的执行方式,例如,限制任务并发数或在特定的线程上运行任务。
任务调度:你可以使用 TaskScheduler
来调度任务的执行,例如,使用 Task.Run
方法时可以指定调度器。
同步上下文:在 UI 应用程序中,TaskScheduler
通常与 SynchronizationContext
一起使用,以确保任务在正确的线程上执行,例如在 UI 线程上更新 UI 元素。
任务调度器的层次结构:TaskScheduler
可以有一个或多个父调度器,这允许你创建复杂的任务调度层次结构。
四、TaskScheduler的简单例子
using System;
using System.Threading.Tasks;class Program
{static void Main(){// 获取默认的任务调度器TaskScheduler defaultScheduler = TaskScheduler.Default;// 创建一个任务Task myTask = new Task(() =>{Console.WriteLine("Task is running on: " + TaskScheduler.Current.ToString());});// 在默认调度器上运行任务myTask.Start(defaultScheduler);// 等待任务完成myTask.Wait();}
}
五、TaskScheduler的完整例子
步骤 1: 创建自定义 TaskScheduler 类
首先,我们需要创建一个继承自 TaskScheduler
的类,并实现必要的方法。
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
{private readonly int _maxDegreeOfParallelism;private readonly ConcurrentQueue<Task> _tasks = new ConcurrentQueue<Task>();private readonly CancellationTokenSource _cts = new CancellationTokenSource();private readonly object _lockObject = new object();private int _currentActiveTasks;public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism){if (maxDegreeOfParallelism <= 0) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");_maxDegreeOfParallelism = maxDegreeOfParallelism;}protected override void QueueTask(Task task){_tasks.Enqueue(task);}protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued){return false;}protected override IEnumerable<Task> GetScheduledTasks(){return _tasks;}public void Start(){for (int i = 0; i < _maxDegreeOfParallelism; i++){Thread thread = new Thread(() =>{try{while (!_tasks.IsEmpty || !_cts.Token.IsCancellationRequested){Task task;if (_tasks.TryDequeue(out task)){base.TryExecuteTask(task);}else{Thread.Yield();}}}catch (Exception ex){Console.WriteLine("Thread encountered an exception: " + ex.Message);}});thread.IsBackground = true;thread.Start();}}public void Stop(){_cts.Cancel();}
}
步骤 2: 使用自定义 TaskScheduler
现在我们可以使用这个自定义的 TaskScheduler
来调度任务。
class Program
{static void Main(string[] args){LimitedConcurrencyLevelTaskScheduler scheduler = new LimitedConcurrencyLevelTaskScheduler(2);scheduler.Start();for (int i = 0; i < 10; i++){Task.Run(() => DoWork(i), scheduler);}Console.WriteLine("Press any key to exit...");Console.ReadKey();scheduler.Stop();}static void DoWork(int workItemId){Console.WriteLine($"Work item {workItemId} is running on thread {Thread.CurrentThread.ManagedThreadId}");Thread.Sleep(1000); // Simulate work by sleeping}
}
解释
LimitedConcurrencyLevelTaskScheduler:这是一个自定义的 TaskScheduler
,它接受一个参数 maxDegreeOfParallelism
,这定义了同时运行的最大任务数。
QueueTask:这个方法将任务添加到一个线程安全的队列中。
TryExecuteTaskInline:这个方法始终返回 false
,因为我们不在调用线程上直接执行任务。
GetScheduledTasks:返回当前队列中的任务。
Start:启动指定数量的线程来处理队列中的任务。
Stop:停止所有线程并取消所有任务。
相关文章:

浅谈C#之任务调度TaskScheduler
一、基本介绍 TaskScheduler 是一个抽象类,用于控制任务的执行方式,特别是它们如何被安排到线程池中的线程上执行。 TaskScheduler 负责将 Task 对象排队并决定何时、以何种方式执行这些任务。 二、TaskScheduler的作用 调度任务:将任务分配…...

SQL server 日常运维命令
一、基础命令 查看当前数据库的版本 SELECT VERSION;查看服务器部分特殊信息 select SERVERPROPERTY(Nedition) as Edition --数据版本,如企业版、开发版等,SERVERPROPERTY(Ncollation) as Collation --数据库字符集,SERVERPROPERTY(Nservername) as Serve…...

基于协同过滤算法+SpringBoot+Vue+MySQL的商品推荐系统
系统展示 用户前台界面 管理员后台界面 系统背景 当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和工作的领域。随着电脑和笔记本的广泛运用,以及…...

VSCode中latex文件(Misplaced alignment tab character .LaTeX
Misplaced alignment tab character &.LaTeX 先给出参考文章1 Misplaced alignment tab character &.LaTeX 把bib文件中的 &改为 and 。删除原有的bbl文件、重新运行 选择这个运行 这个错误在overleaf上并没有遇到、在vscode上遇到了 方法二就是把 &改为…...

如何给电脑设置静态IP地址:详细步骤与指南
在日常生活和工作中,我们经常需要使用电脑连接到网络。通常情况下,电脑会自动获取IP地址,但有时候,由于特定的网络需求或配置,我们可能需要手动为电脑设置静态IP地址。本文将详细介绍如何在Windows和Mac操作系统中为电…...

【Mysql】系统服务启动访问报错问题处理:this is incompatible with sql_mode=only_full_group_by
一、背景: 本来已经正常运行的平台,突然有一天由于对服务器进行部分操作迁移,发现jar可以正常启动,但是访问功能一直报错,监控后台日志后,发现了问题: 报错的具体信息如下: Caused…...

安装oh-my-zsh后报错zsh: command not found: conda问题解决
zsh: command not found: conda问题解决 一、问题介绍与环境介绍 系统为macOS Sonoma 14.5 所用终端为zsh 主要问题:安装了oh-my-zsh之后conda命令在终端中不可用。 二、原因分析 终端中zsh的可访问的程序一般放在/bin, /usr/bin, /usr/local/bin,~/bi…...

避免 PyCharm 将该 Python 脚本作为测试运行
为了避免 PyCharm 将该 Python 脚本作为测试运行(即 pytest 自动捕获),你可以做以下几步来确保该脚本作为普通的 Python 程序执行,而不是作为 pytest 运行。 解决方案: 1. 确保文件名不以 test_ 开头: P…...

【Sqlite】.NET Framework使用Sqlite的注意事项
注意:NuGet引入System.Data.SQLite.Core不要引入System.Data.SQLite 注意:局域网共享链接 正常链接Data Source\\BAT-OCV\SqliteDB\batOCV.db;Version3;PoolingTrue;Max Pool Size100; 局域网链接Data Source\\\BAT-OCV\SqliteDB\batOCV.db;Version3;P…...

2024下《系统集成项目管理工程师》50个高频考点汇总!值得收藏
11月软考已经迫在眉睫,准备考系统集成的小伙伴们开始准备了吗? 这里给大家整理了50个高频考点,涵盖全书80%重点,先把这个存下!再慢慢看书,边看书边背这个,事半功倍。 1、信息安全的基本要素有&…...

Java 远程调用接口(RMI)
Java Remote Method Invocation (RMI) 概述 Java 的 Remote Method Invocation (RMI) 是一种允许 Java 程序调用远程对象的方法。这种方法类似于本地调用,但目标对象实际位于远程 JVM(Java 虚拟机)中。RMI 实现了分布式计算,允许…...

torch.squeeze()
在深度学习中经常会遇见这个函数,现在来说一下这个函数的用法,其实很简单的。 函数作用 函数的作用就是:挤压size为1的维度,挤压也就是remove。如果size不是1的话,那就没变化。 使用说明 在使用的时候,…...

COD论文笔记 BiRefNet
本质还是一个 U 型编码器解码器结构的分割模型。 我可以考虑将©和(d)结合,即对解码器的输入不进行 patchify,同时在各个阶段引入梯度参考信息 最近的相关工作,中间监督、额外先验(频率,梯度,边缘等)取得不错效果 作者观察到…...

表单项标签简单学习
目录 1. 单选框 radio 编辑编辑编辑编辑 2. 复选框 checkbox 编辑编辑编辑 3. 隐藏域 hidden 4. 多行文本框 textarea 编辑编辑 5. 下拉框 select 编辑编辑 6. 选择头像编辑编辑 <!DOCTYPE html> <html lang"en"> <h…...

固态硬盘和机械硬盘区别?固态硬盘和机械硬盘哪个好?
在当今数据时代,硬盘作为电脑里的存储设备在我们的生活和工作中扮演着十分重要的角色。随着存储技术的进步,市场上出现了两种主流硬盘:固态硬盘和机械硬盘。它们各有优劣,那么二者究竟有什么区别?我们又该如何选择呢&a…...

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期]
QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期] 第三期介绍:频道模块之频道成员 目录 QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第三期]第三期介绍:频道模块之频道成员获取子频道在线成员数获取频道成员列表获取频道身份组成员列…...

亚信安全全球云安全SaaS运营总部落地厦门 安全点亮一带一路
近日,第二十四届中国国际投资贸易洽谈会(以下简称“投洽会”)在福建厦门隆重开幕。本届投洽会以“投资链接世界”为主题,积极践行全球发展倡议,服务高质量共建“一带一路”。在投洽会的重要环节,福建省重大…...

在cmd中输入mysql无法运行(环境变量配置保姆级教程)
MySQL环境变量配置 问题概述:解决方法及步骤:检测是否解决问题 问题概述: 下载安装mysql之后,打开cmd界面输入mysql,出现如下提示: mysql 不是内部或外部命令,也不是可运行的程序,或…...

在Webmin上默认状态无法正常显示 Mariadb V11.02及以上版本
OS: Armbian OS 24.5.0 Bookworm Mariadb V11.02及以上版本 Webmin:V2.202 非常小众的问题,主要是记录一下。 如题 Webmin 默认无法 Mariadb V11.02及以上版本 如果对 /etc/webmin/mysql/config 文件作相应调整就可以再现Mariadb管理界面。 路径文件&am…...

C和指针:预处理(#include/define/if...)
预处理器 编译第一步称为预处理(preprocessing)阶段。C预处理器(preprocessor)在源代码编译之前对其进行一些文本性质的操作,包括删除注释、插入被#include 指令包含的文件的内容,替换由#define指令定义的符号以及根据条件编译指令进行编译。 预定义符…...

【Java数据结构】泛型的进阶部分(泛型通配符)
1.❤️❤️前言~🥳🎉🎉🎉 Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的…...

大模型实战一、Ollama+RagFlow 部署本地知识库
大模型实战一、OllamaRagFlow 部署本地知识库 参考你提供的文章,这里是基于 Windows 系统通过 Docker 安装部署 RagFlow 和 Ollama 的本地化大模型知识库的详细教程。本文将指导你如何在 Windows 上使用 Docker 来设置 RagFlow 和 Ollama 环境,并安装通…...

系统工程建模MBSE
################################# ############# 片段一 ############## ################################# 下图采用“V”模式显示了集成的基于模型的系统/嵌入式软件开发流程Harmony。左侧描述了自顶向下的设计流程,而右侧显示了自底而上的从单元测试到最终系统验收测试…...

SVN的使用技巧
SVN(Subversion)是近年来崛起的版本管理工具,因为是免费的,所以用的人还是不少的。故做一些总结。 如果是新手,基本对SVN一点都不了解的话,建议去学习一下这个系统的教程,讲的也很详细Tortoise…...

使用 RabbitMQ 实现秒杀订单系统的异步消息处理
使用 RabbitMQ 实现秒杀订单系统的异步消息处理 在秒杀系统中,如何确保高并发环境下的订单处理稳定高效是个很大的挑战。为了解决这个问题,我们通常会引入消息队列,通过异步处理来削峰填谷。这篇文章将详细讲解如何使用 RabbitMQ 来设计一个…...

oracle19.3单机升级到Oracle19.22
1.补丁包、opatch准备 -rw-r--r-- 1 oracle oinstall 1817908992 9月 10 14:25 p35943157_190000_Linux-x86-64.zip -rw-r--r-- 1 oracle oinstall 133535622 9月 10 14:22 p6880880_190000_Linux-x86-64.zip2.解压补丁包和opatch包 先将原有opatch备份 [oraclecyptdg ~]$…...

半导体的发展--创世新产品介绍
文章目录 半导体的发展 半导体的发展 现代社会对于芯片的需求是越来越多了,90 年代我们能在收音机,电视机,DVD,上面看到芯片的身影,进入 2000 年,电脑,手机逐渐进入中国家庭,中国高…...

Ubuntu WSL使用技巧
0 Preface/Foreword 1 默认为root用户 当下载完成Ubuntu之后,首次登录,当完成初始化后,提示输入新的用户名时候,直接点击右上角的X按钮,再重新登陆,系统会默认使用root权限登录。...

4 个步骤带你快速上手 Einstein Copilot for Tableau
如果你的企业仍未部署或希望迁移至 Tableau Cloud,可考虑订阅 Tableau 高级套件。 自 Einstein Copilot for Tableau 发布以来,相信部分用户已经尝试过在 Tableau Cloud 中借助 AI 对话助理,快速解决数据分析中的问题,获得更准确的…...

C++ | Leetcode C++题解之第386题字典序排数
题目: 题解: class Solution { public:vector<int> lexicalOrder(int n) {vector<int> ret(n);int number 1;for (int i 0; i < n; i) {ret[i] number;if (number * 10 < n) {number * 10;} else {while (number % 10 9 || numbe…...