task 限制任务数量(转自msdn)

  1         public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
  2         {
  3             // Indicates whether the current thread is processing work items.
  4             [ThreadStatic] private static bool _currentThreadIsProcessingItems;
  5
  6             // The maximum concurrency level allowed by this scheduler.
  7             private readonly int _maxDegreeOfParallelism;
  8
  9             // The list of tasks to be executed
 10             private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
 11
 12             // Indicates whether the scheduler is currently processing work items.
 13             private int _delegatesQueuedOrRunning;
 14
 15             // Creates a new instance with the specified degree of parallelism.
 16             public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
 17             {
 18                 if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
 19                 _maxDegreeOfParallelism = maxDegreeOfParallelism;
 20             }
 21
 22             // Gets the maximum concurrency level supported by this scheduler.
 23             public sealed override int MaximumConcurrencyLevel
 24             {
 25                 get { return _maxDegreeOfParallelism; }
 26             }
 27
 28             // Queues a task to the scheduler.
 29             protected sealed override void QueueTask(Task task)
 30             {
 31                 // Add the task to the list of tasks to be processed.  If there aren‘t enough
 32                 // delegates currently queued or running to process tasks, schedule another.
 33                 lock (_tasks)
 34                 {
 35                     _tasks.AddLast(task);
 36                     if (_delegatesQueuedOrRunning < _maxDegreeOfParallelism)
 37                     {
 38                         ++_delegatesQueuedOrRunning;
 39                         NotifyThreadPoolOfPendingWork();
 40                     }
 41                 }
 42             }
 43
 44             // Inform the ThreadPool that there‘s work to be executed for this scheduler.
 45             private void NotifyThreadPoolOfPendingWork()
 46             {
 47                 ThreadPool.UnsafeQueueUserWorkItem(_ =>
 48                 {
 49                     // Note that the current thread is now processing work items.
 50                     // This is necessary to enable inlining of tasks into this thread.
 51                     _currentThreadIsProcessingItems = true;
 52                     try
 53                     {
 54                         // Process all available items in the queue.
 55                         while (true)
 56                         {
 57                             Task item;
 58                             lock (_tasks)
 59                             {
 60                                 // When there are no more items to be processed,
 61                                 // note that we‘re done processing, and get out.
 62                                 if (_tasks.Count == 0)
 63                                 {
 64                                     --_delegatesQueuedOrRunning;
 65                                     break;
 66                                 }
 67
 68                                 // Get the next item from the queue
 69                                 item = _tasks.First.Value;
 70                                 _tasks.RemoveFirst();
 71                             }
 72
 73                             // Execute the task we pulled out of the queue
 74                             TryExecuteTask(item);
 75                         }
 76                     }
 77                     // We‘re done processing items on the current thread
 78                     finally
 79                     {
 80                         _currentThreadIsProcessingItems = false;
 81                     }
 82                 }, null);
 83             }
 84
 85             // Attempts to execute the specified task on the current thread.
 86             protected sealed override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
 87             {
 88                 // If this thread isn‘t already processing a task, we don‘t support inlining
 89                 if (!_currentThreadIsProcessingItems) return false;
 90
 91                 // If the task was previously queued, remove it from the queue
 92                 if (taskWasPreviouslyQueued)
 93                     // Try to run the task.
 94                     if (TryDequeue(task))
 95                         return TryExecuteTask(task);
 96                     else
 97                         return false;
 98                 return TryExecuteTask(task);
 99             }
100
101             // Attempt to remove a previously scheduled task from the scheduler.
102             protected sealed override bool TryDequeue(Task task)
103             {
104                 lock (_tasks)
105                 {
106                     return _tasks.Remove(task);
107                 }
108             }
109
110             // Gets an enumerable of the tasks currently scheduled on this scheduler.
111             protected sealed override IEnumerable<Task> GetScheduledTasks()
112             {
113                 var lockTaken = false;
114                 try
115                 {
116                     Monitor.TryEnter(_tasks, ref lockTaken);
117                     if (lockTaken) return _tasks;
118                     else throw new NotSupportedException();
119                 }
120                 finally
121                 {
122                     if (lockTaken) Monitor.Exit(_tasks);
123                 }
124             }
125         }

使用方法

            // Create a scheduler that uses two threads.
            var lcts = new LimitedConcurrencyLevelTaskScheduler(2);
            var tasks = new List<Task>();

            // Create a TaskFactory and pass it our custom scheduler.
            var factory = new TaskFactory(lcts);
            var cts = new CancellationTokenSource();
            var t = factory.StartNew(() =>
                {

                }, cts.Token);
            tasks.Add(t);
            Task.WaitAll(tasks.ToArray());
            cts.Dispose();或者       Task ttt=new Task((() => {}));       ttt.Start(lcts);
 
时间: 2024-08-27 15:43:28

task 限制任务数量(转自msdn)的相关文章

webapi+Task并行请求不同接口实例

标题的名称定义不知道是否准确,不过我想表达的意思就是使用Task特性来同时请求多个不同的接口,然后合并数据:我想这种场景的开发对于对接过其他公司接口的人不会陌生,本人也是列属于之内,更多的是使用最原始的异步委托的方法去处理,今天抽空写了一个使用4.5新特性Task来处理这种场景:各位看客有什么疑问或者好的建议及分享请博客通知,谢谢. A.项目结构图 B.namespace Pm.V.PM_BLL下面的BaseClass定义如下:   主要是在实例的时候读取各个业务模块的配置文件,初始化一些常用并

线程(Thread,ThreadPool)、Task、Parallel

线程(Thread.ThreadPool) 线程的定义我想大家都有所了解,这里我就不再复述了.我这里主要介绍.NET Framework中的线程(Thread.ThreadPool). .NET Framework中的线程分为两类:1.前台线程:2.后台线程. 1.前台线程 class Program { static void Main(string[] args) { Console.WriteLine("=====Thread====="); TestThread(); Cons

大数据:Spark Core(二)Driver上的Task的生成、分配、调度

1. 什么是Task? 在前面的章节里描述过几个角色,Driver(Client),Master,Worker(Executor),Driver会提交Application到Master进行Worker上的Executor上的调度,显然这些都不是Task. Spark上的几个关系可以这样理解: Application: Application是Driver在构建SparkContent的上下文的时候创建的,就像申报员,现在要构建一个能完成任务的集群,需要申报的是这次需要多少个Executor(可

Task异步编程

Task异步编程中,可以实现在等待耗时任务的同时,执行不依赖于该耗时任务结果的其他同步任务,提高效率. 1.Task异步编程方法签名及返回值: a) 签名有async 修饰符 b) 方法名以 Async 结尾(良好的编码习惯)  根据约定,将“Async”追加到具有 async 修饰符的方法名称.如果某一约定中的事件.基类或接口协定建议其他名称,则可以忽略此约定.例如,你不应重命名常用事件处理程序,例如 btnOpen_Click. c) 返回类型如下: 如果方法有操作数为TResult 类型的

webapi Task

webapi+Task并行请求不同接口实例 标题的名称定义不知道是否准确,不过我想表达的意思就是使用Task特性来同时请求多个不同的接口,然后合并数据:我想这种场景的开发对于对接过其他公司接口的人不会陌生,本人也是列属于之内,更多的是使用最原始的异步委托的方法去处理,今天抽空写了一个使用4.5新特性Task来处理这种场景:各位看客有什么疑问或者好的建议及分享请博客通知,谢谢. A.项目结构图 B.namespace Pm.V.PM_BLL下面的BaseClass定义如下: 主要是在实例的时候读取

使用 Async 和 Await 的异步编程(C# 和 Visual Basic)[msdn.microsoft.com]

看到Microsoft官方一篇关于异步编程的文章,感觉挺好,不敢独享,分享给大家. 原文地址:https://msdn.microsoft.com/zh-cn/library/hh191443.aspx 通过使用异步编程,你可以避免性能瓶颈并增强应用程序的总体响应能力. 但是,编写异步应用程序的传统技术可能比较复杂,使它们难以编写.调试和维护. Visual Studio 2012 引入了一个简化的方法(即异步编程),该方法利用 .NET Framework 4.5 和 Windows 运行时中

微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug

开篇介绍 前些天自己在整理 SSIS 2012 资料的时候发现了一个功能设计上的疑似Bug,在 Script Task 中是可以给只读列表中的变量赋值.我记得以前在 2008 的版本中为了弄明白这个配置,还特意测试过这个细节,获取错误并理解了这个功能.但是现在回去再次测试 2008 的版本时,发现这个功能在 2008 中其实也是错误的,把我印象中的测试结果完全给推翻了,所以到现在已经搞不清楚我当时到底是如果得出这个错误的. 疑似功能 Bug 描述 在 SSIS 包中定义了用户自定义变量 - PV

20181105_线程之Task

Task是基于.net Framework3.0框架, Task使用的线程也是来自于ThreadPool 多线程的两个意义: 优化体验(常见于不卡界面), 提升运行速度(不同线程可以分担运算任务) 总结: //Task6个方法: WaitAll Task.WaitAny(taskList.ToArray());//会阻塞当前线程,等着某个任务完成后,才进入下一行 卡界面; 有好几个重载, 超时. . . WaitAny //Task.WaitAny(taskList.ToArray());//会

Task作为返回值以及Task&lt;TResult&gt;作为返回值

async await return Task https://stackoverflow.com/questions/25191512/async-await-return-task Can somebody explain what does this means into a synchronous method? If I try to change the method to async then VS complain about it. This works: public Tas