TaskScheduler 类 
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
表示一个处理将任务排队到线程中的低级工作的对象。
public ref class TaskScheduler abstractpublic abstract class TaskSchedulertype TaskScheduler = classPublic MustInherit Class TaskScheduler- 继承
- 
				TaskScheduler
示例
以下示例创建一个自定义任务计划程序,用于限制应用使用的线程数。 然后,它会启动两组任务,并显示有关任务和正在执行任务的线程的信息。
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
class Example
{
   static void Main()
   {
       // Create a scheduler that uses two threads.
       LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(2);
       List<Task> tasks = new List<Task>();
       // Create a TaskFactory and pass it our custom scheduler.
       TaskFactory factory = new TaskFactory(lcts);
       CancellationTokenSource cts = new CancellationTokenSource();
       // Use our factory to run a set of tasks.
       Object lockObj = new Object();
       int outputItem = 0;
       for (int tCtr = 0; tCtr <= 4; tCtr++) {
          int iteration = tCtr;
          Task t = factory.StartNew(() => {
                                       for (int i = 0; i < 1000; i++) {
                                          lock (lockObj) {
                                             Console.Write("{0} in task t-{1} on thread {2}   ",
                                                           i, iteration, Thread.CurrentThread.ManagedThreadId);
                                             outputItem++;
                                             if (outputItem % 3 == 0)
                                                Console.WriteLine();
                                          }
                                       }
                                    }, cts.Token);
          tasks.Add(t);
      }
      // Use it to run a second set of tasks.
      for (int tCtr = 0; tCtr <= 4; tCtr++) {
         int iteration = tCtr;
         Task t1 = factory.StartNew(() => {
                                       for (int outer = 0; outer <= 10; outer++) {
                                          for (int i = 0x21; i <= 0x7E; i++) {
                                             lock (lockObj) {
                                                Console.Write("'{0}' in task t1-{1} on thread {2}   ",
                                                              Convert.ToChar(i), iteration, Thread.CurrentThread.ManagedThreadId);
                                                outputItem++;
                                                if (outputItem % 3 == 0)
                                                   Console.WriteLine();
                                             }
                                          }
                                       }
                                    }, cts.Token);
         tasks.Add(t1);
      }
      // Wait for the tasks to complete before displaying a completion message.
      Task.WaitAll(tasks.ToArray());
      cts.Dispose();
      Console.WriteLine("\n\nSuccessful completion.");
   }
}
// Provides a task scheduler that ensures a maximum concurrency level while
// running on top of the thread pool.
public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
{
   // Indicates whether the current thread is processing work items.
   [ThreadStatic]
   private static bool _currentThreadIsProcessingItems;
  // The list of tasks to be executed
   private readonly LinkedList<Task> _tasks = new LinkedList<Task>(); // protected by lock(_tasks)
   // The maximum concurrency level allowed by this scheduler.
   private readonly int _maxDegreeOfParallelism;
   // Indicates whether the scheduler is currently processing work items.
   private int _delegatesQueuedOrRunning = 0;
   // Creates a new instance with the specified degree of parallelism.
   public LimitedConcurrencyLevelTaskScheduler(int maxDegreeOfParallelism)
   {
       if (maxDegreeOfParallelism < 1) throw new ArgumentOutOfRangeException("maxDegreeOfParallelism");
       _maxDegreeOfParallelism = maxDegreeOfParallelism;
   }
   // Queues a task to the scheduler.
   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();
           }
       }
   }
   // Inform the ThreadPool that there's work to be executed for this scheduler.
   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);
   }
   // Attempts to execute the specified task on the current thread.
   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)
          // Try to run the task.
          if (TryDequeue(task))
            return base.TryExecuteTask(task);
          else
             return false;
       else
          return base.TryExecuteTask(task);
   }
   // Attempt to remove a previously scheduled task from the scheduler.
   protected sealed override bool TryDequeue(Task task)
   {
       lock (_tasks) return _tasks.Remove(task);
   }
   // Gets the maximum concurrency level supported by this scheduler.
   public sealed override int MaximumConcurrencyLevel { get { return _maxDegreeOfParallelism; } }
   // Gets an enumerable of the tasks currently scheduled on this scheduler.
   protected sealed override IEnumerable<Task> GetScheduledTasks()
   {
       bool lockTaken = false;
       try
       {
           Monitor.TryEnter(_tasks, ref lockTaken);
           if (lockTaken) return _tasks;
           else throw new NotSupportedException();
       }
       finally
       {
           if (lockTaken) Monitor.Exit(_tasks);
       }
   }
}
// The following is a portion of the output from a single run of the example:
//    'T' in task t1-4 on thread 3   'U' in task t1-4 on thread 3   'V' in task t1-4 on thread 3
//    'W' in task t1-4 on thread 3   'X' in task t1-4 on thread 3   'Y' in task t1-4 on thread 3
//    'Z' in task t1-4 on thread 3   '[' in task t1-4 on thread 3   '\' in task t1-4 on thread 3
//    ']' in task t1-4 on thread 3   '^' in task t1-4 on thread 3   '_' in task t1-4 on thread 3
//    '`' in task t1-4 on thread 3   'a' in task t1-4 on thread 3   'b' in task t1-4 on thread 3
//    'c' in task t1-4 on thread 3   'd' in task t1-4 on thread 3   'e' in task t1-4 on thread 3
//    'f' in task t1-4 on thread 3   'g' in task t1-4 on thread 3   'h' in task t1-4 on thread 3
//    'i' in task t1-4 on thread 3   'j' in task t1-4 on thread 3   'k' in task t1-4 on thread 3
//    'l' in task t1-4 on thread 3   'm' in task t1-4 on thread 3   'n' in task t1-4 on thread 3
//    'o' in task t1-4 on thread 3   'p' in task t1-4 on thread 3   ']' in task t1-2 on thread 4
//    '^' in task t1-2 on thread 4   '_' in task t1-2 on thread 4   '`' in task t1-2 on thread 4
//    'a' in task t1-2 on thread 4   'b' in task t1-2 on thread 4   'c' in task t1-2 on thread 4
//    'd' in task t1-2 on thread 4   'e' in task t1-2 on thread 4   'f' in task t1-2 on thread 4
//    'g' in task t1-2 on thread 4   'h' in task t1-2 on thread 4   'i' in task t1-2 on thread 4
//    'j' in task t1-2 on thread 4   'k' in task t1-2 on thread 4   'l' in task t1-2 on thread 4
//    'm' in task t1-2 on thread 4   'n' in task t1-2 on thread 4   'o' in task t1-2 on thread 4
//    'p' in task t1-2 on thread 4   'q' in task t1-2 on thread 4   'r' in task t1-2 on thread 4
//    's' in task t1-2 on thread 4   't' in task t1-2 on thread 4   'u' in task t1-2 on thread 4
//    'v' in task t1-2 on thread 4   'w' in task t1-2 on thread 4   'x' in task t1-2 on thread 4
//    'y' in task t1-2 on thread 4   'z' in task t1-2 on thread 4   '{' in task t1-2 on thread 4
//    '|' in task t1-2 on thread 4   '}' in task t1-2 on thread 4   '~' in task t1-2 on thread 4
//    'q' in task t1-4 on thread 3   'r' in task t1-4 on thread 3   's' in task t1-4 on thread 3
//    't' in task t1-4 on thread 3   'u' in task t1-4 on thread 3   'v' in task t1-4 on thread 3
//    'w' in task t1-4 on thread 3   'x' in task t1-4 on thread 3   'y' in task t1-4 on thread 3
//    'z' in task t1-4 on thread 3   '{' in task t1-4 on thread 3   '|' in task t1-4 on thread 3
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks
Module Example
   Sub Main()
      ' Create a scheduler that uses two threads. 
      Dim lcts As New LimitedConcurrencyLevelTaskScheduler(2)
      Dim tasks As New List(Of Task)()
      
      ' Create a TaskFactory and pass it our custom scheduler. 
      Dim factory As New TaskFactory(lcts)
      Dim cts As New CancellationTokenSource()
      
      ' Use our factory to run a set of tasks. 
      Dim objLock As New Object()      
      Dim outputItem As Integer 
      For tCtr As Integer = 0 To 4
         Dim iteration As Integer = tCtr
         Dim t As Task = factory.StartNew(Sub()
                                             For i As Integer = 1 To 1000
                                                SyncLock objLock
                                                   Console.Write("{0} in task t-{1} on thread {2}   ", 
                                                   i, iteration, Thread.CurrentThread.ManagedThreadId)
                                                   outputItem += 1
                                                   If outputItem Mod 3 = 0 Then Console.WriteLine()
                                                End SyncLock
                                             Next 
                                          End Sub,
                                cts.Token)
         tasks.Add(t)
      Next 
      ' Use it to run a second set of tasks.                       
      For tCtr As Integer = 0 To 4
         Dim iteration As Integer = tCtr
         Dim t1 As Task = factory.StartNew(Sub()
                                              For outer As Integer = 0 To 10
                                                 For i As Integer = &h21 To &h7E
                                                    SyncLock objLock
                                                       Console.Write("'{0}' in task t1-{1} on thread {2}   ", 
                                                                     Convert.ToChar(i), iteration, Thread.CurrentThread.ManagedThreadId)
                                                       outputItem += 1
                                                       If outputItem Mod 3 = 0 Then Console.WriteLine()
                                                    End SyncLock 
                                                 Next     
                                              Next                                           
                                           End Sub,
                                cts.Token)           
         tasks.Add(t1)
      Next
      
      ' Wait for the tasks to complete before displaying a completion message.
      Task.WaitAll(tasks.ToArray())
      cts.Dispose()
      Console.WriteLine(vbCrLf + vbCrLf + "Successful completion.")
   End Sub 
End Module
' Provides a task scheduler that ensures a maximum concurrency level while 
' running on top of the thread pool.
Public Class LimitedConcurrencyLevelTaskScheduler : Inherits TaskScheduler
   ' Indicates whether the current thread is processing work items.
   <ThreadStatic()> Private Shared _currentThreadIsProcessingItems As Boolean 
   
   ' The list of tasks to be executed 
   Private ReadOnly _tasks As LinkedList(Of Task) = New LinkedList(Of Task)() 
   
   'The maximum concurrency level allowed by this scheduler. 
   Private ReadOnly _maxDegreeOfParallelism As Integer 
   
   ' Indicates whether the scheduler is currently processing work items. 
   Private _delegatesQueuedOrRunning As Integer = 0 ' protected by lock(_tasks)
   
   ' Creates a new instance with the specified degree of parallelism. 
   Public Sub New(ByVal maxDegreeOfParallelism As Integer)
      If (maxDegreeOfParallelism < 1) Then 
         Throw New ArgumentOutOfRangeException("maxDegreeOfParallelism")
      End If
         _maxDegreeOfParallelism = maxDegreeOfParallelism
   End Sub 
   ' Queues a task to the scheduler. 
   Protected Overrides Sub QueueTask(ByVal t As 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. 
      SyncLock (_tasks)
         _tasks.AddLast(t)
         If (_delegatesQueuedOrRunning < _maxDegreeOfParallelism) Then
            _delegatesQueuedOrRunning = _delegatesQueuedOrRunning + 1
            NotifyThreadPoolOfPendingWork()
         End If 
      End SyncLock 
   End Sub 
   
   ' Inform the ThreadPool that there's work to be executed for this scheduler. 
   Private Sub NotifyThreadPoolOfPendingWork()
   
      ThreadPool.UnsafeQueueUserWorkItem(Sub()
                                            ' 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)
                                                  Dim item As Task
                                                  SyncLock (_tasks)
                                                     ' When there are no more items to be processed, 
                                                     ' note that we're done processing, and get out. 
                                                     If (_tasks.Count = 0) Then
                                                        _delegatesQueuedOrRunning = _delegatesQueuedOrRunning - 1
                                                        Exit While 
                                                     End If 
   
                                                     ' Get the next item from the queue
                                                     item = _tasks.First.Value
                                                     _tasks.RemoveFirst()
                                                  End SyncLock 
   
                                                  ' Execute the task we pulled out of the queue 
                                                  MyBase.TryExecuteTask(item)
                                               End While 
                                               ' We're done processing items on the current thread 
                                            Finally
                                               _currentThreadIsProcessingItems = False 
                                            End Try 
                                         End Sub,
                                    Nothing)
   End Sub 
   
   ' Attempts to execute the specified task on the current thread. 
   Protected Overrides Function TryExecuteTaskInline(ByVal t As Task, 
                                                     ByVal taskWasPreviouslyQueued As Boolean) As Boolean 
      ' If this thread isn't already processing a task, we don't support inlining 
      If (Not _currentThreadIsProcessingItems) Then 
         Return False 
      End If 
   
      ' If the task was previously queued, remove it from the queue 
      If (taskWasPreviouslyQueued) Then
         ' Try to run the task. 
         If TryDequeue(t) Then 
            Return MyBase.TryExecuteTask(t)
         Else
            Return False 
         End If     
      Else 
         Return MyBase.TryExecuteTask(t)
      End If   
   End Function 
   
   ' Attempt to remove a previously scheduled task from the scheduler. 
   Protected Overrides Function TryDequeue(ByVal t As Task) As Boolean 
      SyncLock (_tasks)
         Return _tasks.Remove(t)
      End SyncLock 
   End Function 
   
   ' Gets the maximum concurrency level supported by this scheduler. 
   Public Overrides ReadOnly Property MaximumConcurrencyLevel As Integer 
      Get 
         Return _maxDegreeOfParallelism
      End Get 
   End Property 
   
   ' Gets an enumerable of the tasks currently scheduled on this scheduler. 
   Protected Overrides Function GetScheduledTasks() As IEnumerable(Of Task)
      Dim lockTaken As Boolean = False 
      Try
         Monitor.TryEnter(_tasks, lockTaken)
         If (lockTaken) Then 
            Return _tasks.ToArray()
         Else 
            Throw New NotSupportedException()
         End If 
      Finally 
         If (lockTaken) Then
            Monitor.Exit(_tasks)
         End If 
      End Try 
   End Function 
End Class 
' The following is a portion of the output from a single run of the example:
'    'T' in task t1-4 on thread 3   'U' in task t1-4 on thread 3   'V' in task t1-4 on thread 3   
'    'W' in task t1-4 on thread 3   'X' in task t1-4 on thread 3   'Y' in task t1-4 on thread 3   
'    'Z' in task t1-4 on thread 3   '[' in task t1-4 on thread 3   '\' in task t1-4 on thread 3   
'    ']' in task t1-4 on thread 3   '^' in task t1-4 on thread 3   '_' in task t1-4 on thread 3   
'    '`' in task t1-4 on thread 3   'a' in task t1-4 on thread 3   'b' in task t1-4 on thread 3   
'    'c' in task t1-4 on thread 3   'd' in task t1-4 on thread 3   'e' in task t1-4 on thread 3   
'    'f' in task t1-4 on thread 3   'g' in task t1-4 on thread 3   'h' in task t1-4 on thread 3   
'    'i' in task t1-4 on thread 3   'j' in task t1-4 on thread 3   'k' in task t1-4 on thread 3   
'    'l' in task t1-4 on thread 3   'm' in task t1-4 on thread 3   'n' in task t1-4 on thread 3   
'    'o' in task t1-4 on thread 3   'p' in task t1-4 on thread 3   ']' in task t1-2 on thread 4   
'    '^' in task t1-2 on thread 4   '_' in task t1-2 on thread 4   '`' in task t1-2 on thread 4   
'    'a' in task t1-2 on thread 4   'b' in task t1-2 on thread 4   'c' in task t1-2 on thread 4   
'    'd' in task t1-2 on thread 4   'e' in task t1-2 on thread 4   'f' in task t1-2 on thread 4   
'    'g' in task t1-2 on thread 4   'h' in task t1-2 on thread 4   'i' in task t1-2 on thread 4   
'    'j' in task t1-2 on thread 4   'k' in task t1-2 on thread 4   'l' in task t1-2 on thread 4   
'    'm' in task t1-2 on thread 4   'n' in task t1-2 on thread 4   'o' in task t1-2 on thread 4   
'    'p' in task t1-2 on thread 4   'q' in task t1-2 on thread 4   'r' in task t1-2 on thread 4   
'    's' in task t1-2 on thread 4   't' in task t1-2 on thread 4   'u' in task t1-2 on thread 4   
'    'v' in task t1-2 on thread 4   'w' in task t1-2 on thread 4   'x' in task t1-2 on thread 4   
'    'y' in task t1-2 on thread 4   'z' in task t1-2 on thread 4   '{' in task t1-2 on thread 4   
'    '|' in task t1-2 on thread 4   '}' in task t1-2 on thread 4   '~' in task t1-2 on thread 4   
'    'q' in task t1-4 on thread 3   'r' in task t1-4 on thread 3   's' in task t1-4 on thread 3   
'    't' in task t1-4 on thread 3   'u' in task t1-4 on thread 3   'v' in task t1-4 on thread 3   
'    'w' in task t1-4 on thread 3   'x' in task t1-4 on thread 3   'y' in task t1-4 on thread 3   
'    'z' in task t1-4 on thread 3   '{' in task t1-4 on thread 3   '|' in task t1-4 on thread 3
注解
有关此 API 的详细信息,请参阅 TaskScheduler 的补充 API 说明。
构造函数
| TaskScheduler() | 初始化 TaskScheduler。 | 
属性
| Current | 获取与当前正在执行的任务关联的 TaskScheduler。 | 
| Default | 获取由 .NET 提供的默认 TaskScheduler 实例。 | 
| Id | 获取此 TaskScheduler 的唯一 ID。 | 
| MaximumConcurrencyLevel | 指示此 TaskScheduler 能够支持的最大并发级别。 | 
方法
| Equals(Object) | 确定指定对象是否等于当前对象。(继承自 Object) | 
| Finalize() | 释放与此计划程序关联的所有资源。 | 
| FromCurrentSynchronizationContext() | 创建与当前 SynchronizationContext 关联的 TaskScheduler。 | 
| GetHashCode() | 作为默认哈希函数。(继承自 Object) | 
| GetScheduledTasks() | 仅对于调试器支持,生成当前排队到计划程序中等待执行的 Task 实例的枚举。 | 
| GetType() | 获取当前实例的 Type。(继承自 Object) | 
| MemberwiseClone() | 创建当前 Object 的浅表副本。(继承自 Object) | 
| QueueTask(Task) | 将 Task 排队到计划程序中。 | 
| ToString() | 返回表示当前对象的字符串。(继承自 Object) | 
| TryDequeue(Task) | 尝试将以前排队到此计划程序中的 Task 取消排队。 | 
| TryExecuteTask(Task) | 尝试在此计划程序上执行提供的 Task。 | 
| TryExecuteTaskInline(Task, Boolean) | 确定是否可以在此调用中同步执行提供的 Task,如果可以,将执行该任务。 | 
事件
| UnobservedTaskException | 出错的任务中未观察到的异常将触发异常呈报策略时出现,默认情况下会终止进程。 | 
适用于
线程安全性
抽象 TaskScheduler 类型的所有成员都是线程安全的,可以从多个线程同时使用。