TaskScheduler Classe
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Representa um objeto que manipula o trabalho de nível baixo de enfileirar tarefas em threads.
public ref class TaskScheduler abstract
public abstract class TaskScheduler
type TaskScheduler = class
Public MustInherit Class TaskScheduler
- Herança
-
TaskScheduler
Exemplos
O exemplo a seguir cria um agendador de tarefas personalizado que limita o número de threads usados pelo aplicativo. Em seguida, ele inicia dois conjuntos de tarefas e exibe informações sobre a tarefa e o thread no qual a tarefa está sendo executada.
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
Comentários
Para obter mais informações sobre essa API, consulte Comentários da API complementar para TaskScheduler.
Construtores
TaskScheduler() |
Inicializa o TaskScheduler. |
Propriedades
Current |
Obtém o TaskScheduler associado à tarefa em execução no momento. |
Default |
Obtém a instância TaskScheduler padrão fornecida pelo .NET. |
Id |
Obtém a ID exclusiva para este TaskScheduler. |
MaximumConcurrencyLevel |
Indica o nível de simultaneidade máximo ao qual esse TaskScheduler pode dar suporte. |
Métodos
Equals(Object) |
Determina se o objeto especificado é igual ao objeto atual. (Herdado de Object) |
Finalize() |
Libera todos os recursos associados ao agendador. |
FromCurrentSynchronizationContext() |
Cria um TaskScheduler associado ao SynchronizationContext atual. |
GetHashCode() |
Serve como a função de hash padrão. (Herdado de Object) |
GetScheduledTasks() |
Apenas para o suporte do depurador, gera um enumerável de instâncias Task atualmente na fila do Agendador aguardando ser executado. |
GetType() |
Obtém o Type da instância atual. (Herdado de Object) |
MemberwiseClone() |
Cria uma cópia superficial do Object atual. (Herdado de Object) |
QueueTask(Task) |
Enfileira um Task no agendador. |
ToString() |
Retorna uma cadeia de caracteres que representa o objeto atual. (Herdado de Object) |
TryDequeue(Task) |
Tenta remover da fila um Task que anteriormente havia sido enfileirado para esse agendador. |
TryExecuteTask(Task) |
Tenta executar o Task fornecido neste agendador. |
TryExecuteTaskInline(Task, Boolean) |
Determina se o Task fornecido pode ser executado de forma síncrona nessa chamada e, se for possível, o executa. |
Eventos
UnobservedTaskException |
Ocorre quando a exceção não observada da tarefa com falha está prestes a disparar a política de escalonamento de exceção, que, por padrão, encerrará o processo. |
Aplica-se a
Acesso thread-safe
Todos os membros do tipo abstrato TaskScheduler são thread-safe e podem ser usados de vários threads simultaneamente.