首页 > 代码库 > task 限制任务数量(转自msdn)
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 try115 {116 Monitor.TryEnter(_tasks, ref lockTaken);117 if (lockTaken) return _tasks;118 else throw new NotSupportedException();119 }120 finally121 {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);
task 限制任务数量(转自msdn)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。