• 这是参考大佬分享的代码写的有问题请提出指正,谢谢。
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace TaskManager
{
class TaskFactoryMananger
{
//USE
public static void Run()
{ try
{
while (true)
{
LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(10);
TaskFactory factory = new TaskFactory(lcts);
Task[] spiderTask = new Task[] {
factory.StartNew(() =>
{
Log.Logger.Information("{0} Start on thread {1}", "111", Thread.CurrentThread.ManagedThreadId);
Log.Logger.Information("{0} Finish on thread {1}", "111", Thread.CurrentThread.ManagedThreadId);
}),
factory.StartNew(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(3));
Log.Logger.Information("{0} Start on thread {1}", "222", Thread.CurrentThread.ManagedThreadId);
Log.Logger.Information("{0} Finish on thread {1}", "222", Thread.CurrentThread.ManagedThreadId);
}),
factory.StartNew(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(5));
Log.Logger.Information("{0} Start on thread {1}", "333", Thread.CurrentThread.ManagedThreadId);
Log.Logger.Information("{0} Finish on thread {1}", "333", Thread.CurrentThread.ManagedThreadId);
})
};
Task.WaitAll(spiderTask);
Thread.Sleep(TimeSpan.FromMinutes(1));
}
}
catch (AggregateException ex)
{
foreach (Exception inner in ex.InnerExceptions)
{
Log.Logger.Error(inner.Message);
}
}
} /// <summary>
/// Provides a task scheduler that ensures a maximum concurrency level while
/// running on top of the ThreadPool.
/// </summary>
public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
{
/// <summary>Whether the current thread is processing work items.</summary>
[ThreadStatic]
private static bool _currentThreadIsProcessingItems;
/// <summary>The list of tasks to be executed.</summary>
private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
/// <summary>The maximum concurrency level allowed by this scheduler.</summary>
private readonly int _maxDegreeOfParallelism;
/// <summary>Whether the scheduler is currently processing work items.</summary>
private int _delegatesQueuedOrRunning = 0; // protected by lock(_tasks) /// <summary>
/// Initializes an instance of the LimitedConcurrencyLevelTaskScheduler class with the
/// specified degree of parallelism.
/// </summary>
/// <param name="maxDegreeOfParallelism">The maximum degree of parallelism provided by this scheduler.</param>
public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
{
if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
_maxDegreeOfParallelism = maxDegreeOfParallelism;
} /// <summary>Queues a task to the scheduler.</summary>
/// <param name="task">The task to be queued.</param>
protected sealed override void QueueTask(Task task)
{
// Add the task to the list of tasks to be processed. If there aren't enough
// delegates currently queued or running to process tasks, schedule another.
lock (_tasks)
{
_tasks.AddLast(task);
if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
{
++_delegatesQueuedOrRunning;
NotifyThreadPoolOfPendingWork();
}
}
} /// <summary>
/// Informs the ThreadPool that there's work to be executed for this scheduler.
/// </summary>
private void NotifyThreadPoolOfPendingWork()
{
ThreadPool.UnsafeQueueUserWorkItem(_ =>
{
// Note that the current thread is now processing work items.
// This is necessary to enable inlining of tasks into this thread.
_currentThreadIsProcessingItems = true;
try
{
// Process all available items in the queue.
while (true)
{
Task item;
lock (_tasks)
{
// When there are no more items to be processed,
// note that we're done processing, and get out.
if (_tasks.Count == 0)
{
--_delegatesQueuedOrRunning;
break;
} // Get the next item from the queue
item = _tasks.First.Value;
_tasks.RemoveFirst();
} // Execute the task we pulled out of the queue
base.TryExecuteTask(item);
}
}
// We're done processing items on the current thread
finally { _currentThreadIsProcessingItems = false; }
}, null);
} /// <summary>Attempts to execute the specified task on the current thread.</summary>
/// <param name="task">The task to be executed.</param>
/// <param name="taskWasPreviouslyQueued"></param>
/// <returns>Whether the task could be executed on the current thread.</returns>
protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
// If this thread isn't already processing a task, we don't support inlining
if (!_currentThreadIsProcessingItems) return false; // If the task was previously queued, remove it from the queue
if (taskWasPreviouslyQueued) TryDequeue(task); // Try to run the task.
return base.TryExecuteTask(task);
} /// <summary>Attempts to remove a previously scheduled task from the scheduler.</summary>
/// <param name="task">The task to be removed.</param>
/// <returns>Whether the task could be found and removed.</returns>
protected sealed override bool TryDequeue(Task task)
{
lock (_tasks) return _tasks.Remove(task);
} /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary>
public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } } /// <summary>Gets an enumerable of the tasks currently scheduled on this scheduler.</summary>
/// <returns>An enumerable of the tasks currently scheduled.</returns>
protected sealed override IEnumerable<Task> GetScheduledTasks()
{
bool lockTaken = false;
try
{
Monitor.TryEnter(_tasks, ref lockTaken);
if (lockTaken) return _tasks.ToArray();
else throw new NotSupportedException();
}
finally
{
if (lockTaken) Monitor.Exit(_tasks);
}
}
}
}
}

C#任务调度——LimitedConcurrencyLevelTaskScheduler的更多相关文章

  1. 关于 LimitedConcurrencyLevelTaskScheduler 的疑惑

    1. LimitedConcurrencyLevelTaskScheduler 介绍 这个TaskScheduler用过的应该都知道,微软开源的一个任务调度器,它的代码很简单, 也很好懂,但是我没有明 ...

  2. .net 分布式架构之任务调度平台

    开源地址:http://git.oschina.net/chejiangyi/Dyd.BaseService.TaskManager .net 任务调度平台 用于.net dll,exe的任务的挂载, ...

  3. 免费开源的DotNet任务调度组件Quartz.NET(.NET组件介绍之五)

    很多的软件项目中都会使用到定时任务.定时轮询数据库同步,定时邮件通知等功能..NET Framework具有“内置”定时器功能,通过System.Timers.Timer类.在使用Timer类需要面对 ...

  4. Spring Quartz实现任务调度

    任务调度 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情 核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作 任务调度涉及多线程并发.线程池维 ...

  5. Quartz实现任务调度

    一.任务调度概述 在企业级应用中,经常会制定一些"计划任务",即在某个时间点做某件事情,核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作,任务调度涉及多线程并发. ...

  6. 基于ASP.NET MVC(C#)和Quartz.Net组件实现的定时执行任务调度

    http://www.cnblogs.com/bobositlife/p/aspnet-mvc-csharp-quartz-net-timer-task-scheduler.html 在之前的文章&l ...

  7. Quartz任务调度基本使用

    转自:http://www.cnblogs.com/bingoidea/archive/2009/08/05/1539656.html 上一篇:定时器的实现.Java定时器Timer和Quartz介绍 ...

  8. 从零开始学 Java - Spring 使用 Quartz 任务调度定时器

    生活的味道 睁开眼看一看窗外的阳光,伸一个懒腰,拿起放在床一旁的水白开水,甜甜的味道,晃着尾巴东张西望的猫猫,在窗台上舞蹈.你向生活微笑,生活也向你微笑. 请你不要询问我的未来,这有些可笑.你问我你是 ...

  9. #研发中间件介绍#定时任务调度与管理JobCenter

    郑昀 最后更新于2014/11/11 关键词:定时任务.调度.监控报警.Job.crontab.Java 本文档适用人员:研发员工   没有JobCenter时我们要面对的:   电商业务链条很长,业 ...

随机推荐

  1. 【HANA系列】SAP HANA XS Administration Tool登录参数设置

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA XS Admi ...

  2. 应用安全 - 免杀 - 工具 - the-backdoor-factory - 使用|命令 - 汇总

    安装 Kali下方式一: git clone https://github.com/secretsquirrel/the-backdoor-factory方式二: apt-get install ba ...

  3. sublime3配置php开发环境

    Sublime3 3143 1.用包管理器安装SublimeLinter ctrl+shift+p Package Control: install package SublimeLinter 注意: ...

  4. [Vuejs] 给ref赋值需要注意的问题

    1.简单赋值 <div ref="refCon"></div> 访问方式: this.$refs.refCon 2.循环赋值,相同名称 <div v- ...

  5. ef core 动态拼接 条件

    var sql = new List<string>(); var sqlparams = new List<string>(); ; foreach (var p in ph ...

  6. 【洛谷P1119题解】灾后重建——(floyd)

    这道题告诉我,背的掉板子并不能解决一切问题,理解思想才是关键,比如不看题解,我确实想不清楚这题是弗洛伊德求最短路 (我不该自不量力的说我会弗洛伊德了我错了做人果然要谦虚) 灾后重建 题目背景 B地区在 ...

  7. Scrapy学习(二)

    1.在合适的位置创建一个文件夹,创建python虚拟环境: 2.在虚拟环境中安装Scrapy库和pypiwin32库: 命令:pip install scrapy pip install pypiwi ...

  8. redis 哈希 数据类型

    哈希 hset  设置哈希表字段 hset 8000 ename tom   hset 8000 job salesman hget 8000 ename  "tom" hget  ...

  9. Picnic Planning POJ - 1639(度限制生成树)

    解题报告   题意理解 给定一张N个点,M个边的无向图,求出无向图的一颗最小生成树,但是我们要求一号节点的入度不可以超过给定的整数S 也就是一个最小生成树,要求它的一号节点,最多只能和S个节点相连. ...

  10. java.lang.StackOverflowError解决

    在使用JPA的仓储repository进行查询时,经常用到findAllbyId的方法: repository.findAllbyId() 但如果像下面的代码,当list的size量太大的话,就会报栈 ...