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

测试:

输出结果:

参考:

http://msdn.microsoft.com/en-us/library/ee789351(v=vs.110).aspx

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

https://code.msdn.microsoft.com/Samples-for-Parallel-b4b76364/view/SourceCode#content

怎么设置task的最大线程数的更多相关文章

  1. 线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事

    线程池应该设置多少线程合适,怎么样估算出来.最近接触到一些相关资料,现作如下总结. 最开始接触线程池的时候,没有想到就仅仅是设置一个线程池的大小居然还有这么多的学问,汗颜啊. 首先,需要考虑到线程池所 ...

  2. JAVA之工作线程数究竟要设置多少

    一.需求缘起 Web-Server通常有个配置,最大工作线程数,后端服务一般也有个配置,工作线程池的线程数量,这个线程数的配置不同的业务架构师有不同的经验值,有些业务设置为CPU核数的2倍,有些业务设 ...

  3. .NET线程池最大线程数的限制-记一次IIS并发瓶颈

    .NET ThreadPool 最大线程数的限制 IIS并发瓶颈,有几个地方,IIS线程池的最大队列数,工作进程数,最大并发数.这些这里就不展开.主要是最近因为过度使用Task 导致的线程数占用过多, ...

  4. IIS并发瓶颈线程数的限制

    .NET线程池最大线程数的限制-记一次IIS并发瓶颈 https://www.cnblogs.com/7rhythm/p/9964543.html .NET ThreadPool 最大线程数的限制 I ...

  5. 通过设置线程池的最小线程数来提高task的效率,SetMinThreads。

    http://www.cnblogs.com/Charltsing/p/taskpoolthread.html task默认对线程的调度是逐步增加的,连续多次运行并发线程,会提高占用的线程数,而等若干 ...

  6. Nginx设置线程数为整机内核数的俩倍!

    Nginx设置线程数为整机内核数的俩倍!

  7. Tomcat设置最佳线程数总结

    最佳线程数: 性能压测的情况下,起初随着用户数的增加,QPS会上升,当到了一定的阀值之后,用户数量增加QPS并不会增加,或者增加不明显,同时请求的响应时间却大幅增加.这个阀值我们认为是最佳线程数. 为 ...

  8. tomcat最大线程数的设置(转)

    1.Tomcat的server.xml中连接器设置如下 <Connector port="8080" maxThreads="150" minSpareT ...

  9. JMeter命令行方式运行时动态设置线程数及其他属性(动态传参)

    在使用JMeter进行性能测试时,以下情况经常出现: 1.测试过程中,指定运行的线程数.指定运行循环次数不断改变: 2.访问的目标地址发生改变,端口发生改变,需要改写脚本. 上面的问题在GUI中,直接 ...

随机推荐

  1. Unity 区分不同平台

    问题:公司开发的游戏实在android平台上运行,但是我们是在windows平台下进行开发,OK ,经常有些地方开发完之后就要换到android上面,能区分平台的不同就可以对代码做区分处理 回答:un ...

  2. SET GLOBAL slow_query_log=1

    - Variable 'slow_query_log' is a GLOBAL variable and should be set with SET GLOBAL SHOW VARIABLES LI ...

  3. Cluster analysis

    https://en.wikipedia.org/wiki/Cluster_analysis Cluster analysis or clustering is the task of groupin ...

  4. prior knowledge

    https://en.wikipedia.org/wiki/Bayes'_theorem For example, if cancer is related to age, then, using B ...

  5. ifarm 子 父页面方法如何互调

    1.iframe子页面调用父页面js函数 子页面调用父页面函数只需要写上window.praent就可以了.比如调用a()函数,就写成: 代码如下: window.parent.a(); 子页面取父页 ...

  6. taocode

    http://code.taobao.org/project/lang/list/Go/1/

  7. sql CRUD 增删改查复习汇总

    1.创建数据库create database 数据库名称删除数据库drop database 数据库名称2.创建表create table 表名(    列名 类型(长度) 自增长 主键 非空,)自增 ...

  8. DevExpress的所有功能介绍

    https://www.devexpress.com/Subscriptions/New-2016-2.xml?utm_source=AnnounceTry&utm_medium=WhatsN ...

  9. linux epoll 简单demo

    一个简单的epoll demo ,同时接受多个客户端连接,并把接收到的字符串转化为大写字母返回给客户端 #include<stdio.h> #include<arpa/inet.h& ...

  10. java分形树

    import java.awt.*; import java.awt.event.*; import java.util.Random; import javax.swing.*; /** * * @ ...