34 namespace System.Threading.Tasks
36 interface IContinuation
41 class TaskContinuation : IContinuation
49 this.continuationOptions = continuationOptions;
57 int kindCode = (int) kind;
58 var status = task.ContinuationAncestor.Status;
81 }
else if (status ==
TaskStatus.RanToCompletion) {
94 public void Execute ()
96 if (!ContinuationStatusCheck (continuationOptions)) {
103 if (task.IsCompleted)
107 task.RunSynchronouslyCore (task.scheduler);
113 class ActionContinuation : IContinuation
115 readonly Action action;
117 public ActionContinuation (Action action)
119 this.action = action;
122 public void Execute ()
128 class SynchronizationContextContinuation : IContinuation
130 readonly Action action;
131 readonly SynchronizationContext ctx;
133 public SynchronizationContextContinuation (Action action, SynchronizationContext ctx)
135 this.action = action;
139 public void Execute ()
141 ctx.Post (l => ((Action) l) (), action);
145 sealed
class WhenAllContinuation : IContinuation
148 readonly IList<Task> tasks;
151 public WhenAllContinuation (Task owner, IList<Task> tasks)
154 this.counter = tasks.Count;
158 public void Execute ()
160 if (Interlocked.Decrement (ref counter) != 0)
165 bool canceled =
false;
166 List<Exception> exceptions = null;
167 foreach (var task
in tasks) {
168 if (task.IsFaulted) {
169 if (exceptions == null)
170 exceptions =
new List<Exception> ();
172 exceptions.AddRange (task.Exception.InnerExceptions);
176 if (task.IsCanceled) {
181 if (exceptions != null) {
182 owner.TrySetException (
new AggregateException (exceptions));
195 sealed
class WhenAllContinuation<TResult> : IContinuation
197 readonly Task<TResult[]> owner;
198 readonly IList<Task<TResult>> tasks;
201 public WhenAllContinuation (Task<TResult[]> owner, IList<Task<TResult>> tasks)
204 this.counter = tasks.Count;
208 public void Execute ()
210 if (Interlocked.Decrement (ref counter) != 0)
213 bool canceled =
false;
214 List<Exception> exceptions = null;
215 TResult[] results = null;
216 for (
int i = 0; i < tasks.Count; ++i) {
217 var task = tasks [i];
218 if (task.IsFaulted) {
219 if (exceptions == null)
220 exceptions =
new List<Exception> ();
222 exceptions.AddRange (task.Exception.InnerExceptions);
226 if (task.IsCanceled) {
231 if (results == null) {
232 if (canceled || exceptions != null)
235 results =
new TResult[tasks.Count];
238 results[i] = task.Result;
241 if (exceptions != null) {
242 owner.TrySetException (
new AggregateException (exceptions));
251 owner.TrySetResult (results);
255 sealed
class WhenAnyContinuation<T> : IContinuation where T : Task
257 readonly Task<T> owner;
258 readonly IList<T> tasks;
259 AtomicBooleanValue executed;
261 public WhenAnyContinuation (Task<T> owner, IList<T> tasks)
265 executed =
new AtomicBooleanValue ();
268 public void Execute ()
270 if (!executed.TryRelaxedSet ())
273 bool owner_notified =
false;
274 for (
int i = 0; i < tasks.Count; ++i) {
276 if (!task.IsCompleted) {
277 task.RemoveContinuation (
this);
284 owner.TrySetResult (task);
285 owner_notified =
true;
290 sealed
class ManualResetContinuation : IContinuation, IDisposable
292 readonly ManualResetEventSlim evt;
294 public ManualResetContinuation ()
296 this.evt =
new ManualResetEventSlim ();
299 public ManualResetEventSlim Event {
305 public void Dispose ()
310 public void Execute ()
316 sealed
class CountdownContinuation : IContinuation, IDisposable
318 readonly CountdownEvent evt;
320 public CountdownContinuation (
int initialCount)
322 this.evt =
new CountdownEvent (initialCount);
325 public CountdownEvent Event {
331 public void Dispose ()
336 public void Execute ()