zoukankan      html  css  js  c++  java
  • 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);
     
  • 相关阅读:
    TC(Total Commander)文件管理神器
    友盟 集成测试
    Channel SDK (渠道SDK) for Unity
    Prefab Assist插件
    Android资源(图片)命名规范
    FragmentTransaction的commit的异步操作
    面试2
    Git中.gitignore文件不起作用的解决以及Git中的忽略规则介绍
    Android必知必会-Android Studio修改包名
    Http标准协议Android网络框架——NoHttp
  • 原文地址:https://www.cnblogs.com/yzpopulation/p/6124945.html
Copyright © 2011-2022 走看看