TaskScheduler TaskScheduler TaskScheduler TaskScheduler Class

Definition

Stellt ein Objekt dar, das die Einreihung von Aufgaben in Threads auf niedriger Ebene behandelt.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
Vererbung
TaskSchedulerTaskSchedulerTaskSchedulerTaskScheduler

Beispiele

Das folgende Beispiel stammt aus dem Beispiele zur parallelen Programmierung mit .NET Framework 4 auf der MSDN Code Gallery-Website.The following example is taken from the Samples for Parallel Programming with the .NET Framework 4 on the MSDN Code Gallery Web site. Erstellen ein benutzerdefinierten Aufgabenplaners, das die Anzahl der Threads, die von der Anwendung verwendeten einschränkt.It creates a custom task scheduler that limits the number of threads used by the app. Anschließend wird die zwei Sätze von Aufgaben gestartet und zeigt Informationen über die Aufgabe und der Thread, der auf dem die Aufgabe ausgeführt wird.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  

Darüber hinaus sind einige Beispiel-Taskplaner in der Codegalerie verfügbar: Beispiele für die parallele Programmierung mit .NET Framework 4.In addition, several sample task schedulers are available on Code Gallery: Samples for Parallel Programming with the .NET Framework 4.

Hinweise

Eine Instanz von der TaskScheduler Klasse stellt einen Aufgabenplaner.An instance of the TaskScheduler class represents a task scheduler. Durch einen Aufgabenplaner wird sichergestellt, dass die Arbeit einer Aufgabe schließlich ausgeführt wird.A task scheduler ensures that the work of a task is eventually executed.

Der standardmäßige Taskplaner basiert auf dem .NET Framework 4-Threadpool, der Arbeitsübernahme für Lastenausgleich und Threadeinfügung/-deaktivierung für maximalen Durchsatz ermöglicht und für eine gute Gesamtleistung sorgt.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. Dies ist für die meisten Szenarien in der Regel ausreichend.It should be sufficient for most scenarios.

Die TaskScheduler Klasse dient auch als den Erweiterungspunkt für alle anpassbaren Planungslogik.The TaskScheduler class also serves as the extension point for all customizable scheduling logic. Dies schließt die Mechanismen, wie z. B. eine Aufgabe für die Ausführung, und wie geplante Aufgaben planen für Debugger verfügbar gemacht werden sollen.This includes mechanisms such as how to schedule a task for execution, and how scheduled tasks should be exposed to debuggers. Wenn Sie spezielle Funktionen benötigen, können Sie einen benutzerdefinierten Planer erstellen und aktivieren es für bestimmte Aufgaben oder Abfragen.If you require special functionality, you can create a custom scheduler and enable it for specific tasks or queries.

In diesem Thema:In this topic:
Der standardmäßige Aufgabenplaner und der Threadpool der Warteschleife hinzuThe default task scheduler and the thread pool
Der globalen Warteschlange im Vergleich zu lokalen WarteschlangenThe global queue vs. local queues
ArbeitsübernahmeWork stealing
Lang ausgeführte AufgabenLong-running tasks
AufgabeninliningTask inlining
Angeben eines SynchronisierungskontextsSpecifying a synchronization context

Der standardmäßige Aufgabenplaner und der Threadpool der Warteschleife hinzuThe default task scheduler and the thread pool

Der Standardplaner für die Task Parallel Library und PLINQ verwendet den .NET Framework-Threadpool, der durch dargestellt wird die ThreadPool -Klasse, in die Warteschlange und Aufgaben.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. Der Threadpool verwendet, die Informationen, die von bereitgestellte der Task Typ, der den differenzierten Parallelismus (kurzlebige Arbeitseinheiten), die Aufgaben und Abfragen oft darstellen parallele effizient zu unterstützen.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.

Der globalen Warteschlange im Vergleich zu lokalen WarteschlangenThe global queue vs. local queues

Der Threadpool verwaltet Warteschlangen für Threads in jeder Anwendungsdomäne eine globale FIFO (First in, First-Out) zu arbeiten.The thread pool maintains a global FIFO (first-in, first-out) work queue for threads in each application domain. Jedes Mal, wenn ein Programm ruft die ThreadPool.QueueUserWorkItem (oder ThreadPool.UnsafeQueueUserWorkItem) Methode, die Arbeit in dieser freigegebenen Warteschlange abgelegt und schließlich aufheben in der Warteschlange im nächsten Thread, der verfügbar wird.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. Ab .NET Framework 4 wird diese Warteschlange wurde verbessert, um einen sperrenfreien Algorithmus zu verwenden, die ähnelt der ConcurrentQueue<T> Klasse.Starting with the .NET Framework 4, this queue has been improved to use a lock-free algorithm that resembles the ConcurrentQueue<T> class. Mit dieser sperrenfreien Implementierung können Zeitaufwand weniger für der Threadpool bei Aufhebung die Warteschlange gestellt und Arbeitsaufgaben.By using this lock-free implementation, the thread pool spends less time when it queues and de-queues work items. Dieser Leistungsvorteil steht auf alle Programme, die den Threadpool zu verwenden.This performance benefit is available to all programs that use the thread pool.

Aufgaben der obersten Ebene, bei denen es sich um Aufgaben handelt, die nicht im Kontext einer anderen Aufgabe erstellt werden, werden wie jedes andere Arbeitselement in der globalen Warteschlange abgelegt.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. Geschachtelte oder untergeordnete Aufgaben, die im Kontext einer anderen Aufgabe erstellt werden, werden hingegen anders behandelt.However, nested or child tasks, which are created in the context of another task, are handled quite differently. Ein untergeordnetes Element oder eine geschachtelte Aufgabe wird in einer lokalen Warteschlange abgelegt, die speziell für den Thread vorgesehen ist, in dem die übergeordnete Aufgabe ausgeführt wird.A child or nested task is put on a local queue that is specific to the thread on which the parent task is executing. Die übergeordnete Aufgabe ist möglicherweise eine Aufgabe der obersten Ebene. Es kann sich jedoch auch um das untergeordnete Element einer anderen Aufgabe handeln.The parent task may be a top-level task or it also may be the child of another task. Wenn dieser Thread für weitere Arbeitsvorgänge bereit ist, wird zuerst eine Suche in der lokalen Warteschlange ausgeführt.When this thread is ready for more work, it first looks in the local queue. Wenn darin Arbeitselemente warten, kann darauf schnell zugegriffen werden.If work items are waiting there, they can be accessed quickly. Die lokalen Warteschlangen werden zugegriffen, in der Last in, First Out (LIFO)-Prinzip Cacheort beizubehalten und Konflikte zu minimieren.The local queues are accessed in last-in, first-out order (LIFO) to preserve cache locality and reduce contention. Weitere Informationen zu untergeordneten und geschachtelten Aufgaben finden Sie unter angefügte und getrennte untergeordnete Aufgaben.For more information about child tasks and nested tasks, see Attached and Detached Child Tasks.

Die Verwendung von lokalen Warteschlangen nicht nur Druck auf die globale Warteschlange reduziert, sondern nutzt auch den Ort der Daten.The use of local queues not only reduces pressure on the global queue, but also takes advantage of data locality. Arbeitsaufgaben in der lokalen Warteschlange häufig Verweis-Datenstrukturen, die im Arbeitsspeicher physisch nahe beieinander liegen.Work items in the local queue frequently reference data structures that are physically near one another in memory. In diesen Fällen sind die Daten bereits im Cache, nachdem die erste Aufgabe ausgeführt wurde und schnell zugegriffen werden kann.In these cases, the data is already in the cache after the first task has run and can be accessed quickly. Beide Parallel LINQ (PLINQ) und Parallel -Klasse geschachtelte Aufgaben und untergeordnete Aufgaben ausführlich und mit der lokalen Warteschlangen werden deutliche geschwindigkeitssteigerungen erzielt.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.

ArbeitsübernahmeWork stealing

Ab .NET Framework 4, bietet der Threadpool einen Arbeitsübernahme-Algorithmus, um sicherzustellen, dass keine Threads im Leerlauf, während die anderen noch Arbeitsvorgänge in ihre Warteschlangen.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. Wenn ein Threadpoolthread zusätzliche Arbeit übernehmen kann, wird zuerst am Anfang der lokalen Warteschlange, anschließend in der globalen Warteschlange und zuletzt in den lokalen Warteschlangen anderer Threads gesucht.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. Wenn ein Arbeitselement in der lokalen Warteschlange eines anderen Threads gefunden wird, wird zunächst Heuristik angewendet, um sicherzustellen, dass die Arbeit effizient ausgeführt werden kann.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. Wenn dies möglich ist, holt es das Arbeitselement aus der Tail (in FIFO-Reihenfolge).If it can, it de-queues the work item from the tail (in FIFO order). Dadurch werden Konflikte in jeder lokalen Warteschlange verringert und der Datenort beibehalten.This reduces contention on each local queue and preserves data locality. Dank dieser Architektur kann es sich um die Thread-Pool des Lastenausgleichs für arbeiten Sie effizienter als in frühere Versionen.This architecture helps the thread pool load-balance work more efficiently than past versions did.

Lang ausgeführte AufgabenLong-running tasks

Unter Umständen möchten Sie ausdrücklich verhindern, dass eine Aufgabe in einer lokalen Warteschlange abgelegt wird.You may want to explicitly prevent a task from being put on a local queue. Sie wissen möglicherweise z. B., dass eine bestimmte Arbeitsaufgabe für eine relativ lange Zeit ausgeführt wird und daher wahrscheinlich alle anderen Arbeitsaufgaben in der lokalen Warteschlange blockiert.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. In diesem Fall können Sie die System.Threading.Tasks.TaskCreationOptions-Option angeben, die den Planer darauf hinweist, dass u. U. ein weiterer Thread für die Aufgabe erforderlich ist, damit der Fortschritt anderer Threads oder Arbeitsaufgaben in der lokalen Warteschlange nicht blockiert wird.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. Mit dieser Option vermeiden Sie den Threadpool vollständig, einschließlich der globalen und lokalen Warteschlangen.By using this option you avoid the thread pool completely, including the global and local queues.

AufgabeninliningTask inlining

In einigen Fällen, wenn eine Task wird erwartet, es kann synchron ausgeführt werden für den Thread, der den Wartevorgang ausführt.In some cases when a Task is waited on, it may be executed synchronously on the thread that is performing the wait operation. Dies verbessert die Leistung von entfällt die Notwendigkeit ein weiterer Thread aus, und verwenden Sie stattdessen die vorhandenen Threads, die andernfalls blockiert worden wäre.This enhances performance by preventing the need for an additional thread and instead using the existing thread, which would have blocked otherwise. Um Fehler aufgrund von Eintrittsinvarianz zu verhindern, tritt Aufgabeninlining nur auf, wenn das Wartevorgangsziel in der lokalen Warteschlange des relevanten Threads gefunden wird.To prevent errors due to reentrancy, task inlining only occurs when the wait target is found in the relevant thread's local queue.

Angeben eines SynchronisierungskontextsSpecifying a synchronization context

Sie können mit der TaskScheduler.FromCurrentSynchronizationContext-Methode angeben, dass eine Aufgabe für die Ausführung in einem bestimmten Thread geplant werden soll.You can use the TaskScheduler.FromCurrentSynchronizationContext method to specify that a task should be scheduled to run on a particular thread. Dies ist in Frameworks wie Windows Forms und Windows Presentation Foundation hilfreich, wo der Zugriff auf Benutzeroberflächenobjekte oftmals auf Code beschränkt ist, der in dem Thread ausgeführt wird, in dem das Benutzeroberflächenobjekt erstellt wurde.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.

Im folgenden Beispiel wird die TaskScheduler.FromCurrentSynchronizationContext -Methode in einer Windows Presentation Foundation (WPF)-app, um eine Aufgabe auf dem gleichen Thread zu planen, die auf die Steuerelemente der Benutzeroberfläche (UI) erstellt wurde.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. Das Beispiel erstellt ein Mosaik von Bildern, die aus einem angegebenen Verzeichnis nach dem Zufallsprinzip ausgewählt werden.The example creates a mosaic of images that are randomly selected from a specified directory. Die WPF-Objekte werden zum Laden und das Ändern der Bildgröße.The WPF objects are used to load and resize the images. Die unformatierten Pixel werden dann an eine Aufgabe, die verwendet übergeben eine For Schleife, um die Pixeldaten in einem großen Single-Byte-Array zu schreiben.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. Es ist keine Synchronisierung erforderlich, da keine zwei Kacheln, die Elemente des gleichen Arrays belegen.No synchronization is required because no two tiles occupy the same array elements. Die Kacheln können auch in beliebiger Reihenfolge geschrieben werden, da ihre Position unabhängig von anderen Kacheln berechnet wird.The tiles can also be written in any order because their position is calculated independently of any other tile. Das große Array wird anschließend an eine Aufgabe übergeben, die im UI-Thread ausgeführt wird, werden die Pixeldaten in ein Image-Steuerelement geladen.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.

Das Beispiel verschiebt Daten aus der UI-Thread, ändert sie mithilfe von parallelen Schleifen und Task Objekte aus, und übergibt diese an eine Aufgabe, die im UI-Thread ausgeführt wird.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. Dieser Ansatz ist hilfreich, wenn man die Task Parallel Library zu verwenden, um Vorgänge auszuführen, die von der WPF-API nicht unterstützt werden oder nicht schnell genug sind.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. Eine weitere Möglichkeit, ein Bild Mosaic in WPF zu erstellen ist die Verwendung einer System.Windows.Controls.WrapPanel steuern, und fügen Sie Bilder hinzu.Another way to create an image mosaic in WPF is to use a System.Windows.Controls.WrapPanel control and add images to it. Die WrapPanel übernimmt die Aufgabe der Positionierung der Kacheln.The WrapPanel handles the work of positioning the tiles. Diese Aufgabe kann jedoch nur im UI-Thread ausgeführt werden.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

Um das Beispiel zu erstellen, erstellen Sie ein WPF-Anwendungsprojekt in Visual Studio, und nennen Sie sie WPF_CS1 (für eine C# WPF-Projekt) oder WPF_VB1 (für eine Visual Basic-WPF-Projekt).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). Klicken Sie dann folgendermaßen Sie vor:Then do the following:

  1. Ziehen Sie in der Entwurfsansicht ein Image -Steuerelement aus der Toolbox auf der oberen linken Ecke der Entwurfsoberfläche.In design view, drag an Image control from the Toolbox onto the upper left corner of the design surface. In der Namen ins Textfeld die Eigenschaften benennen Sie das Steuerelement "Bild".In the Name textbox of the Properties window, name the control "image".

  2. Ziehen Sie eine Button -Steuerelement aus der Toolbox an der unteren linken Seite des Anwendungsfensters.Drag a Button control from the Toolbox to the lower left part of the application window. Geben Sie in der XAML-Ansicht der Content -Eigenschaft der Schaltfläche als "Make Mosaiken", und geben Sie die Width Eigenschaft als "100".In XAML view, specify the Content property of the button as "Make a mosaic", and specify its Width property as "100". Verbinden der Click -Ereignis mit der button_Click Ereignishandler im Code mit dem Beispiel durch das Hinzufügen Click="button_Click" auf die <Button> Element.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 der Namen ins Textfeld die Eigenschaften benennen Sie das Steuerelement "Button".In the Name textbox of the Properties window, name the control "button".

  3. Ersetzen Sie den gesamten Inhalt der Datei "MainWindow.Xaml.cs" oder "MainWindow.Xaml.vb" durch den Code in diesem Beispiel ein.Replace the entire contents of the MainWindow.xaml.cs or MainWindow.xaml.vb file with the code from this example. Für eine C# WPF project, stellen Sie sicher, dass der Name des Arbeitsbereichs, den Namen des Projekts entspricht.For a C# WPF project, make sure that the name of the workspace matches the project name.

  4. Im Beispiel liest die JPEG-Bilder aus einem Verzeichnis mit dem Namen C:\Users\Public\Pictures\Sample Bilder\.The example reads JPEG images from a directory named C:\Users\Public\Pictures\Sample Pictures\. Erstellen Sie das Verzeichnis und versehen Sie einige Images, oder ändern Sie den Pfad auf einem anderen Verzeichnis verweisen, die Bilder enthält.Either create the directory and place some images in it, or change the path to refer to some other directory that contains images.

In diesem Beispiel weist einige Einschränkungen.This example has some limitations. Beispielsweise werden nur 32-Bit-pro-Pixel-Images unterstützt. Bilder in anderen Formaten sind beschädigt, durch die BitmapImage Objekts während der die Größenänderung.For example, only 32-bits-per-pixel images are supported; images in other formats are corrupted by the BitmapImage object during the resizing operation. Darüber hinaus müssen die Source-Images. alle größer als die Größe der Kacheln sein.Also, the source images must all be larger than the tile size. Als weitere Übung können Sie Funktionen zur Behandlung mehrerer Pixelformate und Dateigrößen hinzufügen.As a further exercise, you can add functionality to handle multiple pixel formats and file sizes.

Konstruktoren

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

Initialisiert das TaskScheduler.Initializes the TaskScheduler.

Eigenschaften

Current Current Current Current

Ruft den zugeordneten TaskScheduler der derzeit ausgeführten Aufgabe ab.Gets the TaskScheduler associated with the currently executing task.

Default Default Default Default

Ruft die TaskScheduler-Standardinstanz ab, die von .NET Framework bereitgestellt wird.Gets the default TaskScheduler instance that is provided by the .NET Framework.

Id Id Id Id

Ruft die eindeutige ID für diesen TaskScheduler ab.Gets the unique ID for this TaskScheduler.

MaximumConcurrencyLevel MaximumConcurrencyLevel MaximumConcurrencyLevel MaximumConcurrencyLevel

Gibt die maximale Parallelitätsebene an, die dieser TaskScheduler unterstützt.Indicates the maximum concurrency level this TaskScheduler is able to support.

Methoden

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

Bestimmt, ob das angegebene Objekt mit dem aktuellen Objekt identisch ist.Determines whether the specified object is equal to the current object.

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

Gibt alle Ressourcen frei, die diesem Planer zugeordnet sind.Frees all resources associated with this scheduler.

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

Erstellt einen TaskScheduler, der dem aktuellen SynchronizationContext zugeordnet ist.Creates a TaskScheduler associated with the current SynchronizationContext.

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

Fungiert als Standardhashfunktion.Serves as the default hash function.

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

Nur für Debuggerunterstützung: Generiert eine Enumeration von Task-Instanzen, die sich gegenwärtig in der Warteschlange des Taskplaners befinden und auf ihre Ausführung warten.For debugger support only, generates an enumerable of Task instances currently queued to the scheduler waiting to be executed.

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

Ruft den Type der aktuellen Instanz ab.Gets the Type of the current instance.

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

Erstellt eine flache Kopie des aktuellen Object.Creates a shallow copy of the current Object.

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

Fügt einen Task in die Warteschlange des Planers ein.Queues a Task to the scheduler.

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

Gibt eine Zeichenfolge zurück, die das aktuelle Objekt darstellt.Returns a string that represents the current object.

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

Versucht, einen zuvor in die Warteschlange dieses Planers eingereihten Task aus der Warteschlange zu entfernen.Attempts to dequeue a Task that was previously queued to this scheduler.

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

Versucht, den angegebenen Task mit diesem Planer auszuführen.Attempts to execute the provided Task on this scheduler.

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

Bestimmt, ob der angegebene Task in diesem Aufruf synchron ausgeführt werden kann, und führt ihn aus, wenn dies der Fall ist.Determines whether the provided Task can be executed synchronously in this call, and if it can, executes it.

Ereignisse

UnobservedTaskException UnobservedTaskException UnobservedTaskException UnobservedTaskException

Tritt auf, kurz bevor eine nicht überwachte Ausnahme eines Tasks, bei dem ein Fehler aufgetreten ist, eine Ausnahmeausweitungsrichtlinie auslöst, was standardmäßig den Prozess beenden würde.Occurs when a faulted task's unobserved exception is about to trigger exception escalation policy, which, by default, would terminate the process.

Gilt für:

Threadsicherheit

Alle Mitglieder der abstrakten TaskScheduler Typs sind threadsicher und können von mehreren Threads gleichzeitig verwendet werden.All members of the abstract TaskScheduler type are thread-safe and may be used from multiple threads concurrently.

Siehe auch