mscorlib(4.0.0.0) API with additions
TaskScheduler.cs
2 using System.Diagnostics;
4 using System.Security;
6 
8 {
10  [DebuggerDisplay("Id={Id}")]
11  [DebuggerTypeProxy(typeof(SystemThreadingTasks_TaskSchedulerDebugView))]
12  [__DynamicallyInvokable]
13  [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
14  [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
15  public abstract class TaskScheduler
16  {
17  internal sealed class SystemThreadingTasks_TaskSchedulerDebugView
18  {
19  private readonly TaskScheduler m_taskScheduler;
20 
21  public int Id => m_taskScheduler.Id;
22 
23  public IEnumerable<Task> ScheduledTasks
24  {
25  [SecurityCritical]
26  get
27  {
28  return m_taskScheduler.GetScheduledTasks();
29  }
30  }
31 
32  public SystemThreadingTasks_TaskSchedulerDebugView(TaskScheduler scheduler)
33  {
34  m_taskScheduler = scheduler;
35  }
36  }
37 
38  private static ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers;
39 
40  private static readonly TaskScheduler s_defaultTaskScheduler = new ThreadPoolTaskScheduler();
41 
42  internal static int s_taskSchedulerIdCounter;
43 
44  private volatile int m_taskSchedulerId;
45 
46  private static EventHandler<UnobservedTaskExceptionEventArgs> _unobservedTaskException;
47 
48  private static readonly object _unobservedTaskExceptionLockObject = new object();
49 
52  [__DynamicallyInvokable]
53  public virtual int MaximumConcurrencyLevel
54  {
55  [__DynamicallyInvokable]
56  get
57  {
58  return int.MaxValue;
59  }
60  }
61 
62  internal virtual bool RequiresAtomicStartTransition => true;
63 
66  [__DynamicallyInvokable]
67  public static TaskScheduler Default
68  {
69  [__DynamicallyInvokable]
70  get
71  {
72  return s_defaultTaskScheduler;
73  }
74  }
75 
78  [__DynamicallyInvokable]
79  public static TaskScheduler Current
80  {
81  [__DynamicallyInvokable]
82  get
83  {
84  TaskScheduler internalCurrent = InternalCurrent;
85  return internalCurrent ?? Default;
86  }
87  }
88 
89  internal static TaskScheduler InternalCurrent
90  {
91  get
92  {
93  Task internalCurrent = Task.InternalCurrent;
94  if (internalCurrent == null || (internalCurrent.CreationOptions & TaskCreationOptions.HideScheduler) != 0)
95  {
96  return null;
97  }
98  return internalCurrent.ExecutingTaskScheduler;
99  }
100  }
101 
104  [__DynamicallyInvokable]
105  public int Id
106  {
107  [__DynamicallyInvokable]
108  get
109  {
110  if (m_taskSchedulerId == 0)
111  {
112  int num = 0;
113  do
114  {
115  num = Interlocked.Increment(ref s_taskSchedulerIdCounter);
116  }
117  while (num == 0);
118  Interlocked.CompareExchange(ref m_taskSchedulerId, num, 0);
119  }
120  return m_taskSchedulerId;
121  }
122  }
123 
125  [__DynamicallyInvokable]
126  public static event EventHandler<UnobservedTaskExceptionEventArgs> UnobservedTaskException
127  {
128  [SecurityCritical]
129  [__DynamicallyInvokable]
130  add
131  {
132  if (value != null)
133  {
135  lock (_unobservedTaskExceptionLockObject)
136  {
137  _unobservedTaskException = (EventHandler<UnobservedTaskExceptionEventArgs>)Delegate.Combine(_unobservedTaskException, value);
138  }
139  }
140  }
141  [SecurityCritical]
142  [__DynamicallyInvokable]
143  remove
144  {
145  lock (_unobservedTaskExceptionLockObject)
146  {
147  _unobservedTaskException = (EventHandler<UnobservedTaskExceptionEventArgs>)Delegate.Remove(_unobservedTaskException, value);
148  }
149  }
150  }
151 
155  [SecurityCritical]
156  [__DynamicallyInvokable]
157  protected internal abstract void QueueTask(Task task);
158 
165  [SecurityCritical]
166  [__DynamicallyInvokable]
167  protected abstract bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued);
168 
172  [SecurityCritical]
173  [__DynamicallyInvokable]
174  protected abstract IEnumerable<Task> GetScheduledTasks();
175 
176  [SecuritySafeCritical]
177  internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued)
178  {
179  TaskScheduler executingTaskScheduler = task.ExecutingTaskScheduler;
180  if (executingTaskScheduler != this && executingTaskScheduler != null)
181  {
182  return executingTaskScheduler.TryRunInline(task, taskWasPreviouslyQueued);
183  }
184  StackGuard currentStackGuard;
185  if (executingTaskScheduler == null || task.m_action == null || task.IsDelegateInvoked || task.IsCanceled || !(currentStackGuard = Task.CurrentStackGuard).TryBeginInliningScope())
186  {
187  return false;
188  }
189  bool flag = false;
190  try
191  {
192  task.FireTaskScheduledIfNeeded(this);
193  flag = TryExecuteTaskInline(task, taskWasPreviouslyQueued);
194  }
195  finally
196  {
197  currentStackGuard.EndInliningScope();
198  }
199  if (flag && !task.IsDelegateInvoked && !task.IsCanceled)
200  {
201  throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_InconsistentStateAfterTryExecuteTaskInline"));
202  }
203  return flag;
204  }
205 
210  [SecurityCritical]
211  [__DynamicallyInvokable]
212  protected internal virtual bool TryDequeue(Task task)
213  {
214  return false;
215  }
216 
217  internal virtual void NotifyWorkItemProgress()
218  {
219  }
220 
221  [SecurityCritical]
222  internal void InternalQueueTask(Task task)
223  {
224  task.FireTaskScheduledIfNeeded(this);
225  QueueTask(task);
226  }
227 
229  [__DynamicallyInvokable]
230  protected TaskScheduler()
231  {
232  if (Debugger.IsAttached)
233  {
234  AddToActiveTaskSchedulers();
235  }
236  }
237 
238  private void AddToActiveTaskSchedulers()
239  {
240  ConditionalWeakTable<TaskScheduler, object> conditionalWeakTable = s_activeTaskSchedulers;
241  if (conditionalWeakTable == null)
242  {
243  Interlocked.CompareExchange(ref s_activeTaskSchedulers, new ConditionalWeakTable<TaskScheduler, object>(), null);
244  conditionalWeakTable = s_activeTaskSchedulers;
245  }
246  conditionalWeakTable.Add(this, null);
247  }
248 
252  [__DynamicallyInvokable]
254  {
255  return new SynchronizationContextTaskScheduler();
256  }
257 
262  [SecurityCritical]
263  [__DynamicallyInvokable]
264  protected bool TryExecuteTask(Task task)
265  {
266  if (task.ExecutingTaskScheduler != this)
267  {
268  throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_ExecuteTask_WrongTaskScheduler"));
269  }
270  return task.ExecuteEntry(bPreventDoubleExecution: true);
271  }
272 
273  internal static void PublishUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs ueea)
274  {
275  lock (_unobservedTaskExceptionLockObject)
276  {
277  _unobservedTaskException?.Invoke(sender, ueea);
278  }
279  }
280 
281  [SecurityCritical]
282  internal Task[] GetScheduledTasksForDebugger()
283  {
284  IEnumerable<Task> scheduledTasks = GetScheduledTasks();
285  if (scheduledTasks == null)
286  {
287  return null;
288  }
289  Task[] array = scheduledTasks as Task[];
290  if (array == null)
291  {
292  array = new List<Task>(scheduledTasks).ToArray();
293  }
294  Task[] array2 = array;
295  foreach (Task task in array2)
296  {
297  int id = task.Id;
298  }
299  return array;
300  }
301 
302  [SecurityCritical]
303  internal static TaskScheduler[] GetTaskSchedulersForDebugger()
304  {
305  if (s_activeTaskSchedulers == null)
306  {
307  return new TaskScheduler[1]
308  {
309  s_defaultTaskScheduler
310  };
311  }
312  ICollection<TaskScheduler> keys = s_activeTaskSchedulers.Keys;
313  if (!keys.Contains(s_defaultTaskScheduler))
314  {
315  keys.Add(s_defaultTaskScheduler);
316  }
317  TaskScheduler[] array = new TaskScheduler[keys.Count];
318  keys.CopyTo(array, 0);
319  TaskScheduler[] array2 = array;
320  foreach (TaskScheduler taskScheduler in array2)
321  {
322  int id = taskScheduler.Id;
323  }
324  return array;
325  }
326  }
327 }
static TaskScheduler?? Current
Gets the T:System.Threading.Tasks.TaskScheduler associated with the currently executing task.
Provides data for the event that is raised when a faulted T:System.Threading.Tasks....
static void PrepareContractedDelegate(Delegate d)
Provides a way for applications to dynamically prepare T:System.AppDomain event delegates.
abstract IEnumerable< Task > GetScheduledTasks()
For debugger support only, generates an enumerable of T:System.Threading.Tasks.Task instances current...
void Add(TKey key, TValue value)
Adds a key to the table.
TaskScheduler()
Initializes the T:System.Threading.Tasks.TaskScheduler.
Represents an object that handles the low-level work of queuing tasks onto threads.
Definition: __Canon.cs:3
Exposes the enumerator, which supports a simple iteration over a collection of a specified type....
Definition: IEnumerable.cs:9
virtual int MaximumConcurrencyLevel
Indicates the maximum concurrency level this T:System.Threading.Tasks.TaskScheduler is able to suppor...
void CopyTo(T[] array, int arrayIndex)
Copies the elements of the T:System.Collections.Generic.ICollection`1 to an T:System....
static Delegate Remove(Delegate source, Delegate value)
Removes the last occurrence of the invocation list of a delegate from the invocation list of another ...
Definition: Delegate.cs:287
abstract bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
Determines whether the provided T:System.Threading.Tasks.Task can be executed synchronously in this c...
static Delegate Combine(Delegate a, Delegate b)
Concatenates the invocation lists of two delegates.
Definition: Delegate.cs:202
static TaskScheduler FromCurrentSynchronizationContext()
Creates a T:System.Threading.Tasks.TaskScheduler associated with the current T:System....
Defines methods to manipulate generic collections.
Definition: ICollection.cs:9
TaskCreationOptions
Specifies flags that control optional behavior for the creation and execution of tasks.
static TaskScheduler Default
Gets the default T:System.Threading.Tasks.TaskScheduler instance that is provided by the ....
SecurityAction
Specifies the security actions that can be performed using declarative security.
static EventHandler< UnobservedTaskExceptionEventArgs > UnobservedTaskException
Occurs when a faulted task's unobserved exception is about to trigger exception escalation policy,...
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
static bool IsAttached
Gets a value that indicates whether a debugger is attached to the process.
Definition: Debugger.cs:25
Represents a collection that can contain many different types of permissions.
int Id
Gets the unique ID for this T:System.Threading.Tasks.TaskScheduler.
bool Contains(T item)
Determines whether the T:System.Collections.Generic.ICollection`1 contains a specific value.
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
Enables compilers to dynamically attach object fields to managed objects.
static int Increment(ref int location)
Increments a specified variable and stores the result, as an atomic operation.
Definition: Interlocked.cs:18
TaskCreationOptions CreationOptions
Gets the T:System.Threading.Tasks.TaskCreationOptions used to create this task.
Definition: Task.cs:1385
Represents a delegate, which is a data structure that refers to a static method or to a class instanc...
Definition: Delegate.cs:15
Enables communication with a debugger. This class cannot be inherited.
Definition: Debugger.cs:11
abstract internal void QueueTask(Task task)
Queues a T:System.Threading.Tasks.Task to the scheduler.
int Count
Gets the number of elements contained in the T:System.Collections.Generic.ICollection`1.
Definition: ICollection.cs:15
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
Definition: List.cs:14
virtual internal bool TryDequeue(Task task)
Attempts to dequeue a T:System.Threading.Tasks.Task that was previously queued to this scheduler.
bool TryExecuteTask(Task task)
Attempts to execute the provided T:System.Threading.Tasks.Task on this scheduler.
The exception that is thrown when a method call is invalid for the object's current state.
T [] ToArray()
Copies the elements of the T:System.Collections.Generic.List`1 to a new array.
Definition: List.cs:1531
Provides atomic operations for variables that are shared by multiple threads.
Definition: Interlocked.cs:10
void Add(T item)
Adds an item to the T:System.Collections.Generic.ICollection`1.
bool IsCanceled
Gets whether this T:System.Threading.Tasks.Task instance has completed execution due to being cancele...
Definition: Task.cs:1336
Represents an asynchronous operation that can return a value.
Definition: Task.cs:18
Provides a set of static methods and properties that provide support for compilers....