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

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

/// <summary>
/// 指定最大并行度的任务调度器
/// </summary>
public class SpecifyDegreeOfParallelismTaskScheduler : TaskScheduler
{
/// <summary>
/// 信号量锁
/// </summary>
private static System.Threading.SemaphoreSlim _lock = new System.Threading.SemaphoreSlim(1); /// <summary>
/// 当前线程是否正在处理任务
/// </summary>
[ThreadStatic]
private static bool _currentThreadIsProcessingItems; /// <summary>
/// 执行的任务队列
/// </summary>
private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); /// <summary>
/// 指定的最大并行度
/// </summary>
private readonly int _maxDegressOfParallelism; /// <summary>
///当前调度器中正在执行的任务数
/// </summary>
private int _runingTasks = 0; /// <summary>
/// 指示此调度器能够支持的最大并发级别。
/// </summary>
public override int MaximumConcurrencyLevel { get { return this._maxDegressOfParallelism; } } /// <summary>
/// 初始化一个可指定最大并行度的任务调度器
/// </summary>
/// <param name="maxDegreeOfParallelism">最大并行度</param>
public SpecifyDegreeOfParallelismTaskScheduler(int maxDegreeOfParallelism)
{
if (maxDegreeOfParallelism < 1)
throw new ArgumentOutOfRangeException("maxDegreeOfParallelism至少为1");
this._maxDegressOfParallelism = maxDegreeOfParallelism;
} /// <summary>
/// 将Task排队到调度器中
/// </summary>
/// <param name="task">要排队的任务</param>
protected override void QueueTask(Task task)
{
_lock.Wait();
try
{
this._tasks.AddLast(task);
if (this._runingTasks < this._maxDegressOfParallelism)
{
++this._runingTasks;
ConsumeTaskOfPending();
}
}
finally
{
_lock.Release();
}
} /// <summary>
/// 尝试在当前线程上执行指定的任务
/// </summary>
/// <param name="task">被执行的任务</param>
/// <param name="taskWasPreviouslyQueued">指定的任务之前是否已经排队</param>
/// <returns>是否能在当前线程执行此任务</returns>
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
//如果当前前程没有正在处理项目,无法内联
if (!_currentThreadIsProcessingItems)
return false; //如果任务之前已经被排队,将其从队列中删除
if (taskWasPreviouslyQueued)
TryDequeue(task);
return base.TryExecuteTask(task);
} /// <summary>
/// 消费队列中等待的任务
/// </summary>
private void ConsumeTaskOfPending()
{
ThreadPool.UnsafeQueueUserWorkItem(p =>
{
_currentThreadIsProcessingItems = true;
try
{
while (true)
{
Task item;
_lock.Wait();
try
{
if (this._tasks.Count == 0)
{
--this._runingTasks;
break;
}
item = this._tasks.First.Value;
this._tasks.RemoveFirst();
}
finally
{
_lock.Release();
}
base.TryExecuteTask(item);
}
}
finally
{
_currentThreadIsProcessingItems = false;
}
}, null);
} /// <summary>
/// 尝试将任务从队列移除
/// </summary>
/// <param name="task">要移除的任务</param>
/// <returns>是否成功将任务从队列中移除</returns>
protected override bool TryDequeue(Task task)
{
_lock.Wait();
try
{
return this._tasks.Remove(task);
}
finally
{
_lock.Release();
}
} /// <summary>
/// 获取当前调度器中已调度任务序列
/// </summary>
/// <returns>可遍历已调度任务序列</returns>
protected override IEnumerable<Task> GetScheduledTasks()
{
_lock.Wait();
try
{
return this._tasks.ToArray();
}
finally
{
_lock.Release();
}
} }

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. mysql获取相隔时间段的数据

    思路:为时间段内的数据进行编序号,然后计算好相隔时间,拿到id作为搜索条件 SELECT * FROM ( SELECT (@i:=@i+1) as i, id, data_send_time FRO ...

  2. php操作redis案例

    <?php     //实例化     $redis = new Redis();     //连接服务器     //默认端口是6379,可不写     $redis->connect( ...

  3. ubuntu 忽略文件的50unattended升级问题

    ubuntu出现这样问题 既然说那个文件扩展名无效,那干脆直接把那个文件删掉 sudo rm /etc/apt/apt.conf.d/20auto-upgrades.ucf-old 删掉之后应该就不会 ...

  4. 唉,可爱的小朋友---(DFS)

    唉,小朋友是比较麻烦的.在一个幼儿园里,老师要上一节游戏课,有N个小朋友要玩游戏,做游戏时要用小皮球,但是幼儿园里只有M个小皮球,而且有些小朋友不喜欢和一些小朋友在一起玩,而只喜欢和另一些小朋友一起玩 ...

  5. ShellExecute 使用

    shellExecute 函数原型及参数含义: function ShellExecute(hWnd:HWND;Operation,FileName,Parameters,Directory:PCha ...

  6. upstream模块调度算法

    反向代理调度算法,轮询算法--——领导如何挑选小弟.迎宾小姐如何挑选服务员. 调度一般分为两类,第一类为静态调度算法,即负载均衡器根据自身设定的规划进行分配,不需要考虑节点的情况,例如,rr.wrr. ...

  7. sj 网页前端与后台数据交互的3种方式

    1.ajax  网页访问 2.form 表单 用户名<input class="yonghu" type="text" id="user&quo ...

  8. postgresql 9源码安装

    安装过程: 1.configuration --prefix=PREFIX install all files under the directory PREFIX instead of usr/lo ...

  9. 最全的MonkeyRunner自动化测试从入门到精通(10)

    三.MonkeyRunner复杂的功能开始学习 (1)获取APK文件中ID的两种方式 Monkeyrunner的环境已经搭建完成,现在对Monkeyrunner做一个简介. Monkeyrunner工 ...

  10. RoR - Advanced Querying

    Seeding the Database: db/seed.rb 可以提供预设data rake db:seed #seeds.rb Person.create! [ {first_name : &q ...