TaskScheduler TaskScheduler TaskScheduler TaskScheduler Class

정의

작업을 스레드의 큐에 대기하는 낮은 수준의 작업을 처리하는 개체를 나타냅니다.Represents an object that handles the low-level work of queuing tasks onto threads.

public ref class TaskScheduler abstract
public abstract class TaskScheduler
type TaskScheduler = class
Public MustInherit Class TaskScheduler
상속
TaskSchedulerTaskSchedulerTaskSchedulerTaskScheduler

예제

다음 예제에서 가져온 것은 Samples for Parallel Programming.NET Framework 4를 사용 하 여 MSDN 코드 갤러리 웹 사이트입니다.The following example is taken from the Samples for Parallel Programming with the .NET Framework 4 on the MSDN Code Gallery Web site. 앱에서 사용 되는 스레드 수를 제한 하는 사용자 지정 작업 스케줄러를 만듭니다.It creates a custom task scheduler that limits the number of threads used by the app. 그런 다음 두 가지 작업 집합을 시작 하 고 작업과 작업이 실행 되는 스레드 관련 정보가 표시 됩니다.It then launches two sets of tasks and displays information about the task and the thread on which the task is executing.

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  

또한 코드 갤러리에서 몇 가지 샘플 작업 스케줄러를 사용할 수 있습니다. .NET Framework 4를 사용한 병렬 프로그래밍에 대 한 샘플입니다.In addition, several sample task schedulers are available on Code Gallery: Samples for Parallel Programming with the .NET Framework 4.

설명

인스턴스는 TaskScheduler 클래스 작업 스케줄러를 나타내는입니다.An instance of the TaskScheduler class represents a task scheduler. 작업 스케줄러는 작업이 실제로 실행되도록 합니다.A task scheduler ensures that the work of a task is eventually executed.

기본 작업 스케줄러는 부하 분산을 위한 작업 가로채기, 최대 처리량을 위한 스레드 삽입/폐기 및 전반적으로 뛰어난 성능을 제공하는 .NET Framework 4 스레드 풀을 기반으로 합니다.The default task scheduler is based on the .NET Framework 4 thread pool, which provides work-stealing for load-balancing, thread injection/retirement for maximum throughput, and overall good performance. 대부분의 시나리오에서는 이것만으로 충분합니다.It should be sufficient for most scenarios.

TaskScheduler 클래스 사용자 지정 가능한 모든 일정 논리에 대 한 확장 지점 역할도 합니다.The TaskScheduler class also serves as the extension point for all customizable scheduling logic. 디버거 실행에 대 한 작업 및 방법을 예약 된 작업을 예약 하는 방법을 제공 해야 같은 메커니즘이 포함 됩니다.This includes mechanisms such as how to schedule a task for execution, and how scheduled tasks should be exposed to debuggers. 특별 한 기능에 필요한 경우 사용자 지정 스케줄러를 만들고 특정 작업 또는 쿼리에 대 한 사용 하도록 설정할 수 있습니다.If you require special functionality, you can create a custom scheduler and enable it for specific tasks or queries.

항목 내용In this topic:
기본 작업 스케줄러 및 스레드 풀The default task scheduler and the thread pool
전역 큐와 로컬 큐 비교The global queue vs. local queues
작업 가로채기Work stealing
장기 실행 작업Long-running tasks
작업 인라인 처리Task inlining
동기화 컨텍스트 지정Specifying a synchronization context

기본 작업 스케줄러 및 스레드 풀The default task scheduler and the thread pool

작업 병렬 라이브러리 및 PLINQ에 대 한 기본 스케줄러를 사용 하 여 표현 되는.NET Framework 스레드 풀을는 ThreadPool 클래스, 큐 및 작업을 실행 합니다.The default scheduler for the Task Parallel Library and PLINQ uses the .NET Framework thread pool, which is represented by the ThreadPool class, to queue and execute work. 스레드 풀에서 제공 하는 정보를 사용 하는 Task 형식 효율적으로 병렬화 하는 작업 및 쿼리가 종종 나타내는 세분화 된 병렬 처리 (짧은 수명의 작업 단위)를 지원 합니다.The thread pool uses the information that is provided by the Task type to efficiently support the fine-grained parallelism (short-lived units of work) that parallel tasks and queries often represent.

전역 큐와 로컬 큐 비교The global queue vs. local queues

스레드 풀 전역 FIFO (선입 선출) 큐 각 애플리케이션 도메인의 스레드에 대 한 작업을 유지 합니다.The thread pool maintains a global FIFO (first-in, first-out) work queue for threads in each application domain. 프로그램을 호출할 때마다 합니다 ThreadPool.QueueUserWorkItem (또는 ThreadPool.UnsafeQueueUserWorkItem) 메서드를 작업이 공유 큐에 배치 되며 최종적으로 사용할 수 있는 다음 스레드 큐 해제 합니다.Whenever a program calls the ThreadPool.QueueUserWorkItem (or ThreadPool.UnsafeQueueUserWorkItem) method, the work is put on this shared queue and eventually de-queued onto the next thread that becomes available. .NET Framework 4부터이 큐가 향상 되었습니다 유사한 잠금 없는 알고리즘을 사용 하 여 ConcurrentQueue<T> 클래스입니다.Starting with the .NET Framework 4, this queue has been improved to use a lock-free algorithm that resembles the ConcurrentQueue<T> class. 이 잠금 없는 구현을 사용 하 여 스레드 풀 데 큐 및 작업 항목 큐에서 제거 하면 시간을 줄입니다.By using this lock-free implementation, the thread pool spends less time when it queues and de-queues work items. 이 성능 혜택은 스레드 풀을 사용 하는 모든 프로그램에 제공 됩니다.This performance benefit is available to all programs that use the thread pool.

다른 작업의 컨텍스트에서 생성되지 않은 작업인 최상위 작업은 다른 작업 항목과 마찬가지로 전역 큐에 배치됩니다.Top-level tasks, which are tasks that are not created in the context of another task, are put on the global queue just like any other work item. 그러나 다른 작업의 컨텍스트에서 생성된 중첩된 작업이나 자식 작업은 전혀 다르게 처리됩니다.However, nested or child tasks, which are created in the context of another task, are handled quite differently. 자식 작업이나 중첩된 작업은 부모 작업이 실행되는 스레드와 관련된 로컬 큐에 배치됩니다.A child or nested task is put on a local queue that is specific to the thread on which the parent task is executing. 부모 작업은 최상위 작업이거나 다른 작업의 자식일 수 있습니다.The parent task may be a top-level task or it also may be the child of another task. 이 스레드가 추가 작업을 수행할 준비가 되면 먼저 로컬 큐를 확인합니다.When this thread is ready for more work, it first looks in the local queue. 작업 항목이 대기 중이면 신속하게 액세스할 수 있습니다.If work items are waiting there, they can be accessed quickly. 로컬 큐를 마지막에 선출 lifo (후입선출) 경합을 줄이고 캐시 집약성을 유지 하려면에서 액세스 됩니다.The local queues are accessed in last-in, first-out order (LIFO) to preserve cache locality and reduce contention. 자식 작업 및 중첩 된 작업에 대 한 자세한 내용은 참조 하세요. 연결 된 자식 작업과 분리 된 자식 작업합니다.For more information about child tasks and nested tasks, see Attached and Detached Child Tasks.

로컬 큐 사용 하 여 전역 큐에 대 한 압력 감소 뿐만 아니라 데이터 집약성의 이점도 있습니다.The use of local queues not only reduces pressure on the global queue, but also takes advantage of data locality. 로컬에서 작업 항목 큐 자주 물리적으로 서로 근처에 있는 메모리 참조 데이터 구조입니다.Work items in the local queue frequently reference data structures that are physically near one another in memory. 이러한 경우에는 데이터가 이미 캐시에서 실행 되는 첫 번째 작업 후 신속 하 게 액세스할 수 있습니다.In these cases, the data is already in the cache after the first task has run and can be accessed quickly. 둘 다 PLINQ (병렬 LINQ)Parallel 중첩 된 작업 및 자식 작업을 광범위 하 게, 클래스 및 속도 크게 향상 로컬 작업 큐를 사용 하 여 합니다.Both Parallel LINQ (PLINQ) and the Parallel class use nested tasks and child tasks extensively, and achieve significant speedups by using the local work queues.

작업 가로채기Work stealing

.NET Framework 4 부터는 스레드 풀 기능도 되는지 확인 하기 위해 스레드가 늘어난 유휴 여전히 다른 큐에 대기 중인 작업이 있는 동안 작업 가로채기 알고리즘을 합니다.Starting with the .NET Framework 4, the thread pool also features a work-stealing algorithm to help make sure that no threads are sitting idle while others still have work in their queues. 스레드 풀 스레드가 추가 작업을 수행할 준비가 되면 먼저 로컬 큐의 시작 부분을 확인한 다음 전역 큐, 다른 스레드의 로컬 큐 순으로 확인합니다.When a thread-pool thread is ready for more work, it first looks at the head of its local queue, then in the global queue, and then in the local queues of other threads. 다른 스레드의 로컬 큐에서 작업 항목을 찾은 경우 먼저 추론을 적용하여 작업을 효율적으로 실행할 수 있는지 확인합니다.If it finds a work item in the local queue of another thread, it first applies heuristics to make sure that it can run the work efficiently. 가능한 경우 FIFO 순서 대로 끝 부분에서 작업 항목을 큐입니다.If it can, it de-queues the work item from the tail (in FIFO order). 이러한 과정을 통해 각 로컬 큐에서의 경합이 줄어들고 데이터 집약성이 유지됩니다.This reduces contention on each local queue and preserves data locality. 이 아키텍처는 스레드 풀의 부하 분산 작업을 이전 버전 보다 효율적으로 수행할 수 있도록 합니다.This architecture helps the thread pool load-balance work more efficiently than past versions did.

장기 실행 작업Long-running tasks

작업이 로컬 큐에 배치되지 않도록 명시적으로 차단할 수도 있습니다.You may want to explicitly prevent a task from being put on a local queue. 예를 들어 특정 작업 항목이 비교적 오랜 시간 동안 실행되며 로컬 큐의 다른 모든 작업 항목을 차단할 가능성이 있음을 알고 있습니다.For example, you may know that a particular work item will run for a relatively long time and is likely to block all other work items on the local queue. 이 경우 로컬 큐의 다른 스레드나 작업 항목의 정방향 진행을 차단하지 않도록 작업에 추가 스레드가 필요할 수도 있다는 힌트를 스케줄러에 제공하는 System.Threading.Tasks.TaskCreationOptions 옵션을 지정할 수 있습니다.In this case, you can specify the System.Threading.Tasks.TaskCreationOptions option, which provides a hint to the scheduler that an additional thread might be required for the task so that it does not block the forward progress of other threads or work items on the local queue. 이 옵션을 사용 하 여 않으려면 스레드 풀 완전히 전역 및 로컬 큐를 포함 합니다.By using this option you avoid the thread pool completely, including the global and local queues.

작업 인라인 처리Task inlining

일부 경우 사례를 Task 대기 중인에 실행 될 수 있습니다 동기적으로 대기 작업을 수행 하는 스레드에서 합니다.In some cases when a Task is waited on, it may be executed synchronously on the thread that is performing the wait operation. 추가 스레드가 필요를 방지 하 고 그렇지 않으면 차단 되었을 기존 스레드를 사용 하 여 성능이 향상 됩니다.This enhances performance by preventing the need for an additional thread and instead using the existing thread, which would have blocked otherwise. 재입력으로 인 한 오류를 방지 하기 위해 작업 인라이닝은 관련 스레드의 로컬 큐에 대기 대상이 있는 경우에만 발생 합니다.To prevent errors due to reentrancy, task inlining only occurs when the wait target is found in the relevant thread's local queue.

동기화 컨텍스트 지정Specifying a synchronization context

TaskScheduler.FromCurrentSynchronizationContext 메서드를 사용하여 작업이 특정 스레드에서 실행 예약되도록 지정할 수 있습니다.You can use the TaskScheduler.FromCurrentSynchronizationContext method to specify that a task should be scheduled to run on a particular thread. 이 기능은 UI 개체가 만들어진 스레드와 동일한 스레드에서 실행되는 코드로 사용자 인터페이스 개체에 대한 액세스가 종종 제한되는 Windows Forms 및 Windows Presentation Foundation과 같은 프레임워크에서 유용합니다.This is useful in frameworks such as Windows Forms and Windows Presentation Foundation where access to user interface objects is often restricted to code that is running on the same thread on which the UI object was created.

다음 예제에서는 TaskScheduler.FromCurrentSynchronizationContext 사용자 인터페이스 (UI) 컨트롤에서 만든 동일한 스레드에서 작업을 예약 하려면 Windows Presentation Foundation (WPF) 앱에서 메서드.The following example uses the TaskScheduler.FromCurrentSynchronizationContext method in a Windows Presentation Foundation (WPF) app to schedule a task on the same thread that the user interface (UI) control was created on. 지정된 된 디렉터리에서 임의로 선택 된 이미지의 시스템을 만듭니다.The example creates a mosaic of images that are randomly selected from a specified directory. WPF 개체를 로드 하 고 이미지를 크기 조정에 사용 됩니다.The WPF objects are used to load and resize the images. 원시 픽셀은 사용 하는 작업에 전달 된 For 큰 단일 바이트 배열로 픽셀 데이터를 작성 하는 루프입니다.The raw pixels are then passed to a task that uses a For loop to write the pixel data into a large single-byte array. 동기화가 필요 하지 되므로 동일한 배열 요소를 차지 하는 두 개의 타일이 없습니다.No synchronization is required because no two tiles occupy the same array elements. 타일의 위치는 다른 타일과 독립적으로 계산 되므로 순서에 관계 없이 작성할 수도 있습니다.The tiles can also be written in any order because their position is calculated independently of any other tile. 대형 배열은 그러면 픽셀 데이터 이미지 컨트롤을 로드 되는 UI 스레드에서 실행 되는 작업에 전달 됩니다.The large array is then passed to a task that runs on the UI thread, where the pixel data is loaded into an Image control.

이 예제에서는 UI 스레드에서 데이터를 이동, 병렬 루프를 사용 하 여 수정 및 Task 개체 및 UI 스레드에서 실행 되는 작업을 다시 전달 합니다.The example moves data off the UI thread, modifies it by using parallel loops and Task objects, and then passes it back to a task that runs on the UI thread. 이 방법은 작업 병렬 라이브러리를 사용 하 여 WPF API에서 지원 되지 않습니다 또는 충분히 빠르지 않은 작업을 수행 해야 할 경우에 유용 합니다.This approach is useful when you have to use the Task Parallel Library to perform operations that either are not supported by the WPF API, or are not sufficiently fast. Wpf에서는 이미지 시스템을 만드는 또 다른 방법은 사용 하는 것을 System.Windows.Controls.WrapPanel 제어 하 고 이미지를 추가 합니다.Another way to create an image mosaic in WPF is to use a System.Windows.Controls.WrapPanel control and add images to it. WrapPanel 타일 배치 작업을 처리 합니다.The WrapPanel handles the work of positioning the tiles. 그러나이 작업 UI 스레드에서 수행할 수만 있습니다.However, this work can only be performed on the UI thread.

using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace WPF_CS1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private int fileCount;
        int colCount;
        int rowCount;
        private int tilePixelHeight;
        private int tilePixelWidth;
        private int largeImagePixelHeight;
        private int largeImagePixelWidth;
        private int largeImageStride;
        PixelFormat format;
        BitmapPalette palette = null;

        public MainWindow()
        {
            InitializeComponent();

            // For this example, values are hard-coded to a mosaic of 8x8 tiles.
            // Each tile is 50 pixels high and 66 pixels wide and 32 bits per pixel.
            colCount = 12;
            rowCount = 8;
            tilePixelHeight = 50;
            tilePixelWidth = 66;
            largeImagePixelHeight = tilePixelHeight * rowCount;
            largeImagePixelWidth = tilePixelWidth * colCount;
            largeImageStride = largeImagePixelWidth * (32 / 8);
            this.Width = largeImagePixelWidth + 40;
            image.Width = largeImagePixelWidth;
            image.Height = largeImagePixelHeight;


        }

        private void button_Click(object sender, RoutedEventArgs e)
        {

            // For best results use 1024 x 768 jpg files at 32bpp.
            string[] files = System.IO.Directory.GetFiles(@"C:\Users\Public\Pictures\Sample Pictures\", "*.jpg");

            fileCount = files.Length;
            Task<byte[]>[] images = new Task<byte[]>[fileCount];
            for (int i = 0; i < fileCount; i++)
            {
                int x = i;
                images[x] = Task.Factory.StartNew(() => LoadImage(files[x]));
            }

            // When they've all been loaded, tile them into a single byte array.
            var tiledImage = Task.Factory.ContinueWhenAll(
                images, (i) => TileImages(i));

            // We are currently on the UI thread. Save the sync context and pass it to
            // the next task so that it can access the UI control "image".
            var UISyncContext = TaskScheduler.FromCurrentSynchronizationContext();

            // On the UI thread, put the bytes into a bitmap and
            // display it in the Image control.
            var t3 = tiledImage.ContinueWith((antecedent) =>
            {
                // Get System DPI.
                Matrix m = PresentationSource.FromVisual(Application.Current.MainWindow)
                                            .CompositionTarget.TransformToDevice;
                double dpiX = m.M11;
                double dpiY = m.M22;

                BitmapSource bms = BitmapSource.Create(largeImagePixelWidth,
                    largeImagePixelHeight,
                    dpiX,
                    dpiY,
                    format,
                    palette, //use default palette
                    antecedent.Result,
                    largeImageStride);
                image.Source = bms;
            }, UISyncContext);
        }

        byte[] LoadImage(string filename)
        {
            // Use the WPF BitmapImage class to load and 
            // resize the bitmap. NOTE: Only 32bpp formats are supported correctly.
            // Support for additional color formats is left as an exercise
            // for the reader. For more information, see documentation for ColorConvertedBitmap.

            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.UriSource = new Uri(filename);
            bitmapImage.DecodePixelHeight = tilePixelHeight;
            bitmapImage.DecodePixelWidth = tilePixelWidth;
            bitmapImage.EndInit();

            format = bitmapImage.Format;
            int size = (int)(bitmapImage.Height * bitmapImage.Width);
            int stride = (int)bitmapImage.Width * 4;
            byte[] dest = new byte[stride * tilePixelHeight];

            bitmapImage.CopyPixels(dest, stride, 0);

            return dest;
        }

        int Stride(int pixelWidth, int bitsPerPixel)
        {
            return (((pixelWidth * bitsPerPixel + 31) / 32) * 4);
        }

        // Map the individual image tiles to the large image
        // in parallel. Any kind of raw image manipulation can be
        // done here because we are not attempting to access any 
        // WPF controls from multiple threads.
        byte[] TileImages(Task<byte[]>[] sourceImages)
        {
            byte[] largeImage = new byte[largeImagePixelHeight * largeImageStride];
            int tileImageStride = tilePixelWidth * 4; // hard coded to 32bpp

            Random rand = new Random();
            Parallel.For(0, rowCount * colCount, (i) =>
            {
                // Pick one of the images at random for this tile.
                int cur = rand.Next(0, sourceImages.Length);
                byte[] pixels = sourceImages[cur].Result;

                // Get the starting index for this tile.
                int row = i / colCount;
                int col = (int)(i % colCount);
                int idx = ((row * (largeImageStride * tilePixelHeight)) + (col * tileImageStride));

                // Write the pixels for the current tile. The pixels are not contiguous
                // in the array, therefore we have to advance the index by the image stride
                // (minus the stride of the tile) for each scanline of the tile.
                int tileImageIndex = 0;
                for (int j = 0; j < tilePixelHeight; j++)
                {
                    // Write the next scanline for this tile.
                    for (int k = 0; k < tileImageStride; k++)
                    {
                        largeImage[idx++] = pixels[tileImageIndex++];
                    }
                    // Advance to the beginning of the next scanline.
                    idx += largeImageStride - tileImageStride;
                }
            });
            return largeImage;
        }
    }
}
Imports System.Threading.Tasks
Imports System.Windows
Imports System.Windows.Media
Imports System.Windows.Media.Imaging

Partial Public Class MainWindow : Inherits Window
    Dim fileCount As Integer
    Dim colCount As Integer
    Dim rowCount As Integer
    Dim tilePixelHeight As Integer
    Dim tilePixelWidth As Integer
    Dim largeImagePixelHeight As Integer
    Dim largeImagePixelWidth As Integer
    Dim largeImageStride As Integer
    Dim format As PixelFormat
    Dim palette As BitmapPalette = Nothing

    Public Sub New()
        InitializeComponent()

        ' For this example, values are hard-coded to a mosaic of 8x8 tiles.
        ' Each tile Is 50 pixels high and 66 pixels wide and 32 bits per pixel.
        colCount = 12
        rowCount = 8
        tilePixelHeight = 50
        tilePixelWidth = 66
        largeImagePixelHeight = tilePixelHeight * rowCount
        largeImagePixelWidth = tilePixelWidth * colCount
        largeImageStride = largeImagePixelWidth * (32 / 8)
        Me.Width = largeImagePixelWidth + 40
        image.Width = largeImagePixelWidth
        image.Height = largeImagePixelHeight
    End Sub

    Private Sub button_Click(sender As Object, e As RoutedEventArgs) _
        Handles button.Click

        ' For best results use 1024 x 768 jpg files at 32bpp.
        Dim files() As String = System.IO.Directory.GetFiles("C:\Users\Public\Pictures\Sample Pictures\", "*.jpg")

        fileCount = files.Length
        Dim images(fileCount - 1) As Task(Of Byte())
        For i As Integer = 0 To fileCount - 1
            Dim x As Integer = i
            images(x) = Task.Factory.StartNew(Function() LoadImage(files(x)))
        Next

        ' When they have all been loaded, tile them into a single byte array.
        'var tiledImage = Task.Factory.ContinueWhenAll(
        '        images, (i) >= TileImages(i));

        '        Dim tiledImage As Task(Of Byte()) = Task.Factory.ContinueWhenAll(images, Function(i As Task(Of Byte())) TileImages(i))
        Dim tiledImage = Task.Factory.ContinueWhenAll(images, Function(i As Task(Of Byte())()) TileImages(i))
        ' We are currently on the UI thread. Save the sync context and pass it to
        ' the next task so that it can access the UI control "image1".
        Dim UISyncContext = TaskScheduler.FromCurrentSynchronizationContext()

        ' On the UI thread, put the bytes into a bitmap and
        ' display it in the Image control.
        Dim t3 = tiledImage.ContinueWith(Sub(antecedent)
                                             ' Get System DPI.
                                             Dim m As Matrix = PresentationSource.FromVisual(Application.Current.MainWindow).CompositionTarget.TransformToDevice
                                             Dim dpiX As Double = m.M11
                                             Dim dpiY As Double = m.M22

                                             ' Use the default palette in creating the bitmap.
                                             Dim bms As BitmapSource = BitmapSource.Create(largeImagePixelWidth,
                                                                                           largeImagePixelHeight,
                                             dpiX,
                                             dpiY,
                                             format,
                                             palette,
                                             antecedent.Result,
                                             largeImageStride)
                                             image.Source = bms
                                         End Sub, UISyncContext)
    End Sub

    Public Function LoadImage(filename As String) As Byte()
        ' Use the WPF BitmapImage class to load and 
        ' resize the bitmap. NOTE: Only 32bpp formats are supported correctly.
        ' Support for additional color formats Is left as an exercise
        ' for the reader. For more information, see documentation for ColorConvertedBitmap.
        Dim bitmapImage As New BitmapImage()
        bitmapImage.BeginInit()
        bitmapImage.UriSource = New Uri(filename)
        bitmapImage.DecodePixelHeight = tilePixelHeight
        bitmapImage.DecodePixelWidth = tilePixelWidth
        bitmapImage.EndInit()

        format = bitmapImage.Format
        Dim size As Integer = CInt(bitmapImage.Height * bitmapImage.Width)
        Dim stride As Integer = CInt(bitmapImage.Width * 4)
        Dim dest(stride * tilePixelHeight - 1) As Byte

        bitmapImage.CopyPixels(dest, stride, 0)

        Return dest
    End Function

    Function Stride(pixelWidth As Integer, bitsPerPixel As Integer) As Integer
        Return (((pixelWidth * bitsPerPixel + 31) / 32) * 4)
    End Function

    ' Map the individual image tiles to the large image
    ' in parallel. Any kind of raw image manipulation can be
    ' done here because we are Not attempting to access any 
    ' WPF controls from multiple threads.
    Function TileImages(sourceImages As Task(Of Byte())()) As Byte()
        Dim largeImage(largeImagePixelHeight * largeImageStride - 1) As Byte
        Dim tileImageStride As Integer = tilePixelWidth * 4 ' hard coded To 32bpp

        Dim rand As New Random()
        Parallel.For(0, rowCount * colCount, Sub(i)
                                                 ' Pick one of the images at random for this tile.
                                                 Dim cur As Integer = rand.Next(0, sourceImages.Length)
                                                 Dim pixels() As Byte = sourceImages(cur).Result

                                                 ' Get the starting index for this tile.
                                                 Dim row As Integer = i \ colCount
                                                 Dim col As Integer = i Mod colCount
                                                 Dim idx As Integer = ((row * (largeImageStride * tilePixelHeight)) + (col * tileImageStride))

                                                 ' Write the pixels for the current tile. The pixels are Not contiguous
                                                 ' in the array, therefore we have to advance the index by the image stride
                                                 ' (minus the stride of the tile) for each scanline of the tile.
                                                 Dim tileImageIndex As Integer = 0
                                                 For j As Integer = 0 To tilePixelHeight - 1
                                                     ' Write the next scanline for this tile.
                                                     For k As Integer = 0 To tileImageStride - 1
                                                         largeImage(idx) = pixels(tileImageIndex)
                                                         idx += 1
                                                         tileImageIndex += 1
                                                     Next
                                                     ' Advance to the beginning of the next scanline.
                                                     idx += largeImageStride - tileImageStride
                                                 Next
                                             End Sub)
        Return largeImage
    End Function
End Class

예제를 만들려면 Visual Studio에서 WPF 애플리케이션 프로젝트를 만들고 WPF_CS1 이름을 (에 대 한는 C# WPF 프로젝트) 또는 WPF_VB1 (Visual Basic WPF 프로젝트를)에 대 한 합니다.To create the example, create a WPF application project in Visual Studio and name it WPF_CS1 (for a C# WPF project) or WPF_VB1 (for a Visual Basic WPF project). 다음을 수행 합니다.Then do the following:

  1. 디자인 뷰에서 Image 에서 제어를 도구 상자 디자인 화면의 왼쪽된 위 모퉁이에 있습니다.In design view, drag an Image control from the Toolbox onto the upper left corner of the design surface. 이름 의 텍스트 상자를 속성 창 "제어"이미지 이름입니다.In the Name textbox of the Properties window, name the control "image".

  2. 끌어서를 Button 에서 제어 합니다 도구 상자 애플리케이션 창의 왼쪽된 아래 부분에 합니다.Drag a Button control from the Toolbox to the lower left part of the application window. XAML 뷰에서 지정 된 Content "Make 시스템"으로 단추의 속성 지정 해당 Width 속성을 "100"으로 합니다.In XAML view, specify the Content property of the button as "Make a mosaic", and specify its Width property as "100". 연결 합니다 Click 이벤트를 button_Click 이벤트 처리기를 추가 하 여 예제의 코드에 정의 된 Click="button_Click"<Button> 요소.Connect the Click event with the button_Click event handler defined in the example's code by adding Click="button_Click" to the <Button> element. 이름 의 텍스트 상자를 속성 창 "단추" 컨트롤 이름입니다.In the Name textbox of the Properties window, name the control "button".

  3. 이 예제에서 코드를 사용 하 여 MainWindow.xaml.vb 또는 MainWindow.xaml.cs 파일의 전체 내용을 대체 합니다.Replace the entire contents of the MainWindow.xaml.cs or MainWindow.xaml.vb file with the code from this example. 에 대 한는 C# WPF 프로젝트에서 작업 영역의 이름을 프로젝트 이름이 일치 하는지 확인 합니다.For a C# WPF project, make sure that the name of the workspace matches the project name.

  4. 이 예제에서는 C:\Users\Public\Pictures\Sample 사진 라는 디렉터리에서 JPEG 이미지를 읽고\합니다.The example reads JPEG images from a directory named C:\Users\Public\Pictures\Sample Pictures\. 디렉터리 만들기, 일부 이미지를 배치 또는 이미지가 포함 된 일부 다른 디렉터리를 가리키도록 경로 변경 합니다.Either create the directory and place some images in it, or change the path to refer to some other directory that contains images.

이 예제에서는 몇 가지 제한 사항이 있습니다.This example has some limitations. 예를 들어만 32 비트-픽셀당 이미지는 지원 됩니다. 다른 형식의 이미지에서 손상 된를 BitmapImage 개체 크기 조정 작업 중입니다.For example, only 32-bits-per-pixel images are supported; images in other formats are corrupted by the BitmapImage object during the resizing operation. 또한 소스 이미지 모두 여야 합니다 타일 크기를 초과 합니다.Also, the source images must all be larger than the tile size. 자세한 연습을 여러 픽셀 형식 및 파일 크기를 처리할 수 있는 기능을 추가할 수 있습니다.As a further exercise, you can add functionality to handle multiple pixel formats and file sizes.

생성자

TaskScheduler() TaskScheduler() TaskScheduler() TaskScheduler()

TaskScheduler을 초기화합니다.Initializes the TaskScheduler.

속성

Current Current Current Current

현재 실행 중인 작업과 연결된 TaskScheduler를 가져옵니다.Gets the TaskScheduler associated with the currently executing task.

Default Default Default Default

.NET Framework에 의해 제공된 기본 TaskScheduler 인스턴스를 가져옵니다.Gets the default TaskScheduler instance that is provided by the .NET Framework.

Id Id Id Id

TaskScheduler의 고유 ID를 가져옵니다.Gets the unique ID for this TaskScheduler.

MaximumConcurrencyLevel MaximumConcurrencyLevel MaximumConcurrencyLevel MaximumConcurrencyLevel

TaskScheduler가 지원할 수 있는 최대 동시성 수준을 나타냅니다.Indicates the maximum concurrency level this TaskScheduler is able to support.

메서드

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

지정한 개체와 현재 개체가 같은지 여부를 확인합니다.Determines whether the specified object is equal to the current object.

(Inherited from Object)
Finalize() Finalize() Finalize() Finalize()

이 스케줄러에 연결된 모든 리소스를 해제합니다.Frees all resources associated with this scheduler.

FromCurrentSynchronizationContext() FromCurrentSynchronizationContext() FromCurrentSynchronizationContext() FromCurrentSynchronizationContext()

현재 SynchronizationContext와 연결된 TaskScheduler를 만듭니다.Creates a TaskScheduler associated with the current SynchronizationContext.

GetHashCode() GetHashCode() GetHashCode() GetHashCode()

기본 해시 함수로 작동합니다.Serves as the default hash function.

(Inherited from Object)
GetScheduledTasks() GetScheduledTasks() GetScheduledTasks() GetScheduledTasks()

디버거를 지원하기 위해 현재 스케줄러의 큐에 대기되어 실행을 기다리고 있는 Task 인스턴스의 열거 가능한 형식을 생성합니다.For debugger support only, generates an enumerable of Task instances currently queued to the scheduler waiting to be executed.

GetType() GetType() GetType() GetType()

현재 인스턴스의 Type을 가져옵니다.Gets the Type of the current instance.

(Inherited from Object)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

현재 Object의 단순 복사본을 만듭니다.Creates a shallow copy of the current Object.

(Inherited from Object)
QueueTask(Task) QueueTask(Task) QueueTask(Task) QueueTask(Task)

Task를 스케줄러의 큐에 대기합니다.Queues a Task to the scheduler.

ToString() ToString() ToString() ToString()

현재 개체를 나타내는 문자열을 반환합니다.Returns a string that represents the current object.

(Inherited from Object)
TryDequeue(Task) TryDequeue(Task) TryDequeue(Task) TryDequeue(Task)

이전에 이 스케줄러의 큐에 대기된 Task를 큐에서 제거하려고 합니다.Attempts to dequeue a Task that was previously queued to this scheduler.

TryExecuteTask(Task) TryExecuteTask(Task) TryExecuteTask(Task) TryExecuteTask(Task)

이 스케줄러에 제공된 Task를 실행하려고 합니다.Attempts to execute the provided Task on this scheduler.

TryExecuteTaskInline(Task, Boolean) TryExecuteTaskInline(Task, Boolean) TryExecuteTaskInline(Task, Boolean) TryExecuteTaskInline(Task, Boolean)

제공된 Task를 이 호출에서 동기적으로 실행할 수 있는지 여부를 확인하고 실행 가능할 경우 실행합니다.Determines whether the provided Task can be executed synchronously in this call, and if it can, executes it.

이벤트

UnobservedTaskException UnobservedTaskException UnobservedTaskException UnobservedTaskException

오류가 발생한 작업의 확인되지 않은 예외가 기본적으로 프로세스를 종료하는 예외 에스컬레이션 정책을 트리거하려고 할 때 발생합니다.Occurs when a faulted task's unobserved exception is about to trigger exception escalation policy, which, by default, would terminate the process.

적용 대상

스레드 보안

모든 추상 멤버 TaskScheduler 형식은 스레드로부터 안전 하 고 여러 스레드에서 동시에 사용할 수 있습니다.All members of the abstract TaskScheduler type are thread-safe and may be used from multiple threads concurrently.

추가 정보