mscorlib(4.0.0.0) API with additions
TaskAwaiter.cs
4 using System.Security;
6 using System.Threading;
8 
10 {
12  [__DynamicallyInvokable]
13  [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
15  {
16  private readonly Task m_task;
17 
22  [__DynamicallyInvokable]
23  public bool IsCompleted
24  {
25  [__DynamicallyInvokable]
26  get
27  {
28  return m_task.IsCompleted;
29  }
30  }
31 
32  internal TaskAwaiter(Task task)
33  {
34  m_task = task;
35  }
36 
42  [SecuritySafeCritical]
43  [__DynamicallyInvokable]
44  public void OnCompleted(Action continuation)
45  {
46  OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: true);
47  }
48 
54  [SecurityCritical]
55  [__DynamicallyInvokable]
56  public void UnsafeOnCompleted(Action continuation)
57  {
58  OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: false);
59  }
60 
65  [__DynamicallyInvokable]
66  public void GetResult()
67  {
68  ValidateEnd(m_task);
69  }
70 
71  internal static void ValidateEnd(Task task)
72  {
73  if (task.IsWaitNotificationEnabledOrNotRanToCompletion)
74  {
75  HandleNonSuccessAndDebuggerNotification(task);
76  }
77  }
78 
79  private static void HandleNonSuccessAndDebuggerNotification(Task task)
80  {
81  if (!task.IsCompleted)
82  {
83  bool flag = task.InternalWait(-1, default(CancellationToken));
84  }
85  task.NotifyDebuggerOfWaitCompletionIfNecessary();
86  if (!task.IsRanToCompletion)
87  {
88  ThrowForNonSuccess(task);
89  }
90  }
91 
92  private static void ThrowForNonSuccess(Task task)
93  {
94  switch (task.Status)
95  {
96  case TaskStatus.Canceled:
97  task.GetCancellationExceptionDispatchInfo()?.Throw();
98  throw new TaskCanceledException(task);
99  case TaskStatus.Faulted:
100  {
101  ReadOnlyCollection<ExceptionDispatchInfo> exceptionDispatchInfos = task.GetExceptionDispatchInfos();
102  if (exceptionDispatchInfos.Count > 0)
103  {
104  exceptionDispatchInfos[0].Throw();
105  break;
106  }
107  throw task.Exception;
108  }
109  }
110  }
111 
112  [MethodImpl(MethodImplOptions.NoInlining)]
113  [SecurityCritical]
114  internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext, bool flowExecutionContext)
115  {
116  if (continuation == null)
117  {
118  throw new ArgumentNullException("continuation");
119  }
120  StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
121  if (TplEtwProvider.Log.IsEnabled() || Task.s_asyncDebuggingEnabled)
122  {
123  continuation = OutputWaitEtwEvents(task, continuation);
124  }
125  task.SetContinuationForAwait(continuation, continueOnCapturedContext, flowExecutionContext, ref stackMark);
126  }
127 
128  private static Action OutputWaitEtwEvents(Task task, Action continuation)
129  {
130  if (Task.s_asyncDebuggingEnabled)
131  {
132  Task.AddToActiveTasks(task);
133  }
134  TplEtwProvider etwLog = TplEtwProvider.Log;
135  if (etwLog.IsEnabled())
136  {
137  Task internalCurrent = Task.InternalCurrent;
138  Task task2 = AsyncMethodBuilderCore.TryGetContinuationTask(continuation);
139  etwLog.TaskWaitBegin(internalCurrent?.m_taskScheduler.Id ?? TaskScheduler.Default.Id, internalCurrent?.Id ?? 0, task.Id, TplEtwProvider.TaskWaitBehavior.Asynchronous, task2?.Id ?? 0, Thread.GetDomainID());
140  }
141  return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, delegate
142  {
143  if (Task.s_asyncDebuggingEnabled)
144  {
145  Task.RemoveFromActiveTasks(task.Id);
146  }
147  Guid oldActivityThatWillContinue = default(Guid);
148  bool flag = etwLog.IsEnabled();
149  if (flag)
150  {
151  Task internalCurrent2 = Task.InternalCurrent;
152  etwLog.TaskWaitEnd(internalCurrent2?.m_taskScheduler.Id ?? TaskScheduler.Default.Id, internalCurrent2?.Id ?? 0, task.Id);
153  if (etwLog.TasksSetActivityIds && (task.Options & (TaskCreationOptions)1024) != 0)
154  {
155  EventSource.SetCurrentThreadActivityId(TplEtwProvider.CreateGuidForTaskID(task.Id), out oldActivityThatWillContinue);
156  }
157  }
158  continuation();
159  if (flag)
160  {
161  etwLog.TaskWaitContinuationComplete(task.Id);
162  if (etwLog.TasksSetActivityIds && (task.Options & (TaskCreationOptions)1024) != 0)
163  {
164  EventSource.SetCurrentThreadActivityId(oldActivityThatWillContinue);
165  }
166  }
167  });
168  }
169  }
172  [__DynamicallyInvokable]
173  [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
175  {
176  private readonly Task<TResult> m_task;
177 
182  [__DynamicallyInvokable]
183  public bool IsCompleted
184  {
185  [__DynamicallyInvokable]
186  get
187  {
188  return m_task.IsCompleted;
189  }
190  }
191 
192  internal TaskAwaiter(Task<TResult> task)
193  {
194  m_task = task;
195  }
196 
202  [SecuritySafeCritical]
203  [__DynamicallyInvokable]
204  public void OnCompleted(Action continuation)
205  {
206  TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: true);
207  }
208 
214  [SecurityCritical]
215  [__DynamicallyInvokable]
216  public void UnsafeOnCompleted(Action continuation)
217  {
218  TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: false);
219  }
220 
226  [__DynamicallyInvokable]
227  public TResult GetResult()
228  {
229  TaskAwaiter.ValidateEnd(m_task);
230  return m_task.ResultOnSuccess;
231  }
232  }
233 }
TResult GetResult()
Ends the wait for the completion of the asynchronous task.
Definition: TaskAwaiter.cs:227
Represents an operation that schedules continuations when it completes.
Propagates notification that operations should be canceled.
Provides the base class for a generic read-only collection.
void Throw()
Throws the exception that is represented by the current T:System.Runtime.ExceptionServices....
TaskStatus Status
Gets the T:System.Threading.Tasks.TaskStatus of this task.
Definition: Task.cs:1294
void UnsafeOnCompleted(Action continuation)
Schedules the continuation action for the asynchronous task that is associated with this awaiter.
Definition: TaskAwaiter.cs:56
TaskStatus
Represents the current stage in the lifecycle of a T:System.Threading.Tasks.Task.
Definition: TaskStatus.cs:5
Represents an object that handles the low-level work of queuing tasks onto threads.
Definition: __Canon.cs:3
int Count
Gets the number of elements contained in the T:System.Collections.ObjectModel.ReadOnlyCollection`1 in...
delegate void Action()
Encapsulates a method that has no parameters and does not return a value.
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.
Provides an object that waits for the completion of an asynchronous task.
Definition: TaskAwaiter.cs:14
bool IsCompleted
Gets a value that indicates whether the asynchronous task has completed.
Definition: TaskAwaiter.cs:24
int Id
Gets the unique ID for this T:System.Threading.Tasks.TaskScheduler.
bool IsCompleted
Gets whether this T:System.Threading.Tasks.Task has completed.
Definition: Task.cs:1370
static void SetCurrentThreadActivityId(Guid activityId)
[Supported in the .NET Framework 4.5.1 and later versions] Sets the activity ID on the current thread...
Definition: EventSource.cs:649
Provides the ability to create events for event tracing for Windows (ETW).
Definition: EventSource.cs:21
void GetResult()
Ends the wait for the completion of the asynchronous task.
Definition: TaskAwaiter.cs:66
MethodImplOptions
Defines the details of how a method is implemented.
int Id
Gets an ID for this T:System.Threading.Tasks.Task instance.
Definition: Task.cs:1233
AggregateException Exception
Gets the T:System.AggregateException that caused the T:System.Threading.Tasks.Task to end prematurely...
Definition: Task.cs:1277
static int GetDomainID()
Returns a unique application domain identifier.
Definition: Thread.cs:1108
void OnCompleted(Action continuation)
Sets the action to perform when the T:System.Runtime.CompilerServices.TaskAwaiter object stops waitin...
Definition: TaskAwaiter.cs:44
Represents an awaiter that schedules continuations when an await operation completes.
Represents an asynchronous operation that can return a value.
Definition: Task.cs:18
Represents an exception used to communicate task cancellation.
Creates and controls a thread, sets its priority, and gets its status.
Definition: Thread.cs:18