可指定并行度的任务调度器

https://social.msdn.microsoft.com/Forums/zh-CN/b02ba3b4-539b-46b7-af6b-a5ca3a61a309/task?forum=visualcshartzhchs

  1. /// <summary>
  2. /// 指定最大并行度的任务调度器
  3. /// </summary>
  4. public class SpecifyDegreeOfParallelismTaskScheduler : TaskScheduler
  5. {
  6. /// <summary>
  7. /// 信号量锁
  8. /// </summary>
  9. private static System.Threading.SemaphoreSlim _lock = new System.Threading.SemaphoreSlim(1);
  10. /// <summary>
  11. /// 当前线程是否正在处理任务
  12. /// </summary>
  13. [ThreadStatic]
  14. private static bool _currentThreadIsProcessingItems;
  15. /// <summary>
  16. /// 执行的任务队列
  17. /// </summary>
  18. private readonly LinkedList<Task> _tasks = new LinkedList<Task>();
  19. /// <summary>
  20. /// 指定的最大并行度
  21. /// </summary>
  22. private readonly int _maxDegressOfParallelism;
  23. /// <summary>
  24. ///当前调度器中正在执行的任务数
  25. /// </summary>
  26. private int _runingTasks = 0;
  27. /// <summary>
  28. /// 指示此调度器能够支持的最大并发级别。
  29. /// </summary>
  30. public override int MaximumConcurrencyLevel { get { return this._maxDegressOfParallelism; } }
  31. /// <summary>
  32. /// 初始化一个可指定最大并行度的任务调度器
  33. /// </summary>
  34. /// <param name="maxDegreeOfParallelism">最大并行度</param>
  35. public SpecifyDegreeOfParallelismTaskScheduler(int maxDegreeOfParallelism)
  36. {
  37. if (maxDegreeOfParallelism < 1)
  38. throw new ArgumentOutOfRangeException("maxDegreeOfParallelism至少为1");
  39. this._maxDegressOfParallelism = maxDegreeOfParallelism;
  40. }
  41. /// <summary>
  42. /// 将Task排队到调度器中
  43. /// </summary>
  44. /// <param name="task">要排队的任务</param>
  45. protected override void QueueTask(Task task)
  46. {
  47. _lock.Wait();
  48. try
  49. {
  50. this._tasks.AddLast(task);
  51. if (this._runingTasks < this._maxDegressOfParallelism)
  52. {
  53. ++this._runingTasks;
  54. ConsumeTaskOfPending();
  55. }
  56. }
  57. finally
  58. {
  59. _lock.Release();
  60. }
  61. }
  62. /// <summary>
  63. /// 尝试在当前线程上执行指定的任务
  64. /// </summary>
  65. /// <param name="task">被执行的任务</param>
  66. /// <param name="taskWasPreviouslyQueued">指定的任务之前是否已经排队</param>
  67. /// <returns>是否能在当前线程执行此任务</returns>
  68. protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
  69. {
  70. //如果当前前程没有正在处理项目,无法内联
  71. if (!_currentThreadIsProcessingItems)
  72. return false;
  73. //如果任务之前已经被排队,将其从队列中删除
  74. if (taskWasPreviouslyQueued)
  75. TryDequeue(task);
  76. return base.TryExecuteTask(task);
  77. }
  78. /// <summary>
  79. /// 消费队列中等待的任务
  80. /// </summary>
  81. private void ConsumeTaskOfPending()
  82. {
  83. ThreadPool.UnsafeQueueUserWorkItem(p =>
  84. {
  85. _currentThreadIsProcessingItems = true;
  86. try
  87. {
  88. while (true)
  89. {
  90. Task item;
  91. _lock.Wait();
  92. try
  93. {
  94. if (this._tasks.Count == 0)
  95. {
  96. --this._runingTasks;
  97. break;
  98. }
  99. item = this._tasks.First.Value;
  100. this._tasks.RemoveFirst();
  101. }
  102. finally
  103. {
  104. _lock.Release();
  105. }
  106. base.TryExecuteTask(item);
  107. }
  108. }
  109. finally
  110. {
  111. _currentThreadIsProcessingItems = false;
  112. }
  113. }, null);
  114. }
  115. /// <summary>
  116. /// 尝试将任务从队列移除
  117. /// </summary>
  118. /// <param name="task">要移除的任务</param>
  119. /// <returns>是否成功将任务从队列中移除</returns>
  120. protected override bool TryDequeue(Task task)
  121. {
  122. _lock.Wait();
  123. try
  124. {
  125. return this._tasks.Remove(task);
  126. }
  127. finally
  128. {
  129. _lock.Release();
  130. }
  131. }
  132. /// <summary>
  133. /// 获取当前调度器中已调度任务序列
  134. /// </summary>
  135. /// <returns>可遍历已调度任务序列</returns>
  136. protected override IEnumerable<Task> GetScheduledTasks()
  137. {
  138. _lock.Wait();
  139. try
  140. {
  141. return this._tasks.ToArray();
  142. }
  143. finally
  144. {
  145. _lock.Release();
  146. }
  147. }
  148. }

C# 可指定并行度任务调度器的更多相关文章

  1. TaskScheduler一个.NET版任务调度器

    TaskScheduler是一个.net版的任务调度器.概念少,简单易用. 支持SimpleTrigger触发器,指定固定时间间隔和执行次数: 支持CronTrigger触发器,用强大的Cron表达式 ...

  2. Windows:任务调度器

    Windows 服务器系列: Windows:查看IP地址,IP地址对应的机器名,占用的端口,以及占用该端口的应用程 Windows:使用Dos命令管理服务(Services) Windows:任务调 ...

  3. [原创]php任务调度器 hellogerard/jobby

    目录 简介 安装 标准使用 选项 项目实践 简介 一个强大的php层面上的定时任务调度器, 无需修改系统层面的crontab 实际中, php 结合 crontab 来实现定时任务是一种经得住考验的实 ...

  4. 企业级任务调度框架Quartz(6) 任务调度器(Scheduler)

    前序:      我们已经在前面的内容能里看到了,我们用 Scheduler 来管理我们的 Job:创建并关联触发器以使 Job 能被触发执行:以及如可选择 calendar 为给定的时程安排提供更多 ...

  5. 2. SOFAJRaft源码分析—JRaft的定时任务调度器是怎么做的?

    看完这个实现之后,感觉还是要多看源码,多研究.其实JRaft的定时任务调度器是基于Netty的时间轮来做的,如果没有看过Netty的源码,很可能并不知道时间轮算法,也就很难想到要去使用这么优秀的定时调 ...

  6. 在springboot项目中引入quartz任务调度器。

    quartz是一个非常强大的任务调度器.我们可能使用它来管理我们的项目,常见的是做业绩统计等等.当然它的功能远不止这些.我们在这里不介绍quartz的原理,下面讲讲如何在springboot中使用qu ...

  7. 开源基于docker的任务调度器pipeline,比`quartzs` 更强大的分布式任务调度器

    pipeline 分布式任务调度器 目标: 基于docker的布式任务调度器, 比quartzs,xxl-job 更强大的分布式任务调度器. 可以将要执行的任务打包为docker镜像,或者选择已有镜像 ...

  8. C#TaskScheduler 任务调度器的原理

    什么是TaskScheduler? SynchronizationContext是对"调度程序(scheduler)"的通用抽象.个别框架会有自己的抽象调度程序,比如System. ...

  9. 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类

    21_BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类 BasicTaskScheduler基本任务调度器 BasicTaskScheduler基 ...

随机推荐

  1. Galera Cluster mysql+keepalived集群部署

    1.卸载mysql 查找本机安装的mysqlrpm -qa | grep -i mysql --nodeps --force rpm -ev MySQL-server-5.6.15-1.el6.x86 ...

  2. vue3版本到vue2版本的桥接工具

    vue2的命令可以正常使用.

  3. [转] - Weiflow——微博机器学习框架

    Weiflow--微博机器学习框架 本文从开发效率(易用性).可扩展性.执行效率三个方面,介绍了微博机器学习框架Weiflow在微博的应用和最佳实践. 在上期<基于Spark的大规模机器学习在微 ...

  4. PYTHON SOCKET编程简介

    原文地址: PYTHON SOCKET编程详细介绍   Python 提供了两个基本的 socket 模块. 第一个是 Socket,它提供了标准的 BSD Sockets API. 第二个是 Soc ...

  5. PHP指定时间戳/日期加一天,一年,一周,一月

    PHP指定时间戳加上1天,1周,1月,一年其实是不需要用上什么函数的!指定时间戳本身就是数字整型,我们只需要再计算1天,1周它的秒数相加即可! 博主搜索php指定时间戳加一天一年,结果许多的文章给出来 ...

  6. Python学习之旅(二十二)

    Python基础知识(21):IO编程 一.文件读写 读写文件就是请求操作系统打开一个文件对象(文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象 ...

  7. 个人小爱好:Operating System:three easy pieces---第6章第4节_担心并发问题?

    担心并发问题? 微妙,上下文切换大约6微妙.而,现在的系统有着级数级别的提升,在2-3GHz的处理起中消耗只有亚微妙级. 但应该注意到,不是所有的系统性能都跟着CPU性能的提升而提升,根据Ouster ...

  8. itoa()、atoi()、任意进制转换

    头文件:<stdlib.h> itoa --功能:将任意类型的数字转换为字符串.在<stdlib.h>中与之有相反功能的函数是atoi. atoi----功 能: 将字符串转换 ...

  9. 数组/Array/Tuple/yield

    数组 如果需要使用同一类型的多个对象,就可以考虑使用集合和数组.如果需要使用不同类型的多个对象,可以考虑使用Tuple(元组) 数组的声明 在声明数组时,应先定义数组元素中的类型,其后是一对空方括号和 ...

  10. JavaScript 数组插入元素并排序

    1.插入类排序 插入类排序的思想是:在一个已排好序的序列区内,对待排序的无序序列中的记录逐个进行处理,每一步都讲待排序的记录和已排好的序列中的记录进行比较,然后有序的插入到该序列中,直到所有待排序的记 ...