C# 可指定并行度任务调度器
可指定并行度的任务调度器
/// <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# 可指定并行度任务调度器的更多相关文章
- TaskScheduler一个.NET版任务调度器
		
TaskScheduler是一个.net版的任务调度器.概念少,简单易用. 支持SimpleTrigger触发器,指定固定时间间隔和执行次数: 支持CronTrigger触发器,用强大的Cron表达式 ...
 - Windows:任务调度器
		
Windows 服务器系列: Windows:查看IP地址,IP地址对应的机器名,占用的端口,以及占用该端口的应用程 Windows:使用Dos命令管理服务(Services) Windows:任务调 ...
 - [原创]php任务调度器 hellogerard/jobby
		
目录 简介 安装 标准使用 选项 项目实践 简介 一个强大的php层面上的定时任务调度器, 无需修改系统层面的crontab 实际中, php 结合 crontab 来实现定时任务是一种经得住考验的实 ...
 - 企业级任务调度框架Quartz(6) 任务调度器(Scheduler)
		
前序: 我们已经在前面的内容能里看到了,我们用 Scheduler 来管理我们的 Job:创建并关联触发器以使 Job 能被触发执行:以及如可选择 calendar 为给定的时程安排提供更多 ...
 - 2. SOFAJRaft源码分析—JRaft的定时任务调度器是怎么做的?
		
看完这个实现之后,感觉还是要多看源码,多研究.其实JRaft的定时任务调度器是基于Netty的时间轮来做的,如果没有看过Netty的源码,很可能并不知道时间轮算法,也就很难想到要去使用这么优秀的定时调 ...
 - 在springboot项目中引入quartz任务调度器。
		
quartz是一个非常强大的任务调度器.我们可能使用它来管理我们的项目,常见的是做业绩统计等等.当然它的功能远不止这些.我们在这里不介绍quartz的原理,下面讲讲如何在springboot中使用qu ...
 - 开源基于docker的任务调度器pipeline,比`quartzs` 更强大的分布式任务调度器
		
pipeline 分布式任务调度器 目标: 基于docker的布式任务调度器, 比quartzs,xxl-job 更强大的分布式任务调度器. 可以将要执行的任务打包为docker镜像,或者选择已有镜像 ...
 - C#TaskScheduler  任务调度器的原理
		
什么是TaskScheduler? SynchronizationContext是对"调度程序(scheduler)"的通用抽象.个别框架会有自己的抽象调度程序,比如System. ...
 - 21 BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类
		
21_BasicTaskScheduler基本任务调度器(一)——Live555源码阅读(一)任务调度相关类 BasicTaskScheduler基本任务调度器 BasicTaskScheduler基 ...
 
随机推荐
- poj3087  Shuffle'm Up(模拟)
			
Shuffle'm Up Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10766 Accepted: 4976 Des ...
 - vue2中使用transition
			
最终效果为 div元素从右向左出现, 然后从左向右消失. transition标签包裹要移动的元素: css 样式: 其中: 1: 为div元素显示时的状态 2: 为div元素移动的过程 (进入 ...
 - jquery验证规则
			
<!DOCTYPE html><html><head><meta charset="utf-8"><title>菜鸟教程 ...
 - IDEA多个服务打断点 各服务乱窜的问题
			
Setting --> Build, Execution, Deployment --> Debugger 选中即可
 - Luogu 1309 - 瑞士轮 - [归并排序]
			
题目链接:https://www.luogu.org/problemnew/show/P1309 题解: 每次比赛前,每个人都是按照分数降序排好的,那么比赛完后,将选手按输赢分成两组,顺序依然按照原顺 ...
 - CentOS中service命令与/etc/init.d的关系以及centos7的变化
			
缘由 由于个人经常在ubuntu和centos 系统中切换,习惯了以前的 ubuntu中 通过 /etc/init.d/xxx 进行软件服务控制.后来发现centos7中换了服务的控制方式:servi ...
 - DELPHI中完成端口(IOCP)的简单分析(2)
			
DELPHI中完成端口(IOCP)的简单分析(2) 今天我写一下关于DELPHI编写完成端口(IOCP)的工作者线程中的东西.希望各位能提出批评意见.上次我写了关于常见IOCP的代码,对于IOCP ...
 - 线程 学习教程(一): Java中终止(销毁)线程的方法
			
结束线程有以下三种方法:(1)设置退出标志,使线程正常退出,也就是当run()方法完成后线程终止 (2)使用interrupt()方法中断线程 (3)使用stop方法强行终止线程(不推荐使用,Thre ...
 - int bool 字符串 列表 字典 集合
			
1.int和bool 输出i的最大二进制位数inti = 1000 print(i.bit_length()) 2. str int bool list set dict tuple 相互转换 pr ...
 - JavaBean持久化
			
JavaBean持久化并不局限于Swing构件的存储,可以使用该机制存储任意对象的集合,只要遵守一些简单的规则即可. XMLEncoder内置了对下列类型的支持: ●null ●所有基本类型及其包装器 ...