2 using System.Collections.Concurrent;
3 using System.Collections.Generic;
4 using System.Diagnostics.Contracts;
7 using System.Threading;
8 using System.Threading.Tasks;
12 public static class TaskExtensions
14 public static Task<T2> Then<T1, T2>(this Task<T1> first, Func<T1, Task<T2>> next)
17 throw new ArgumentNullException("first");
19 throw new ArgumentNullException("next");
20 Contract.EndContractBlock();
21 return Then(first, next, CancellationToken.None);
24 public static Task Then<T1>(this Task<T1> first, Func<T1, Task> next)
27 throw new ArgumentNullException("first");
29 throw new ArgumentNullException("next");
30 Contract.EndContractBlock();
31 return Then(first, next, CancellationToken.None);
34 public static Task<T2> Then<T1, T2>(this Task<T1> first, Func<T1, Task<T2>> next, CancellationToken cancellationToken)
37 throw new ArgumentNullException("first");
39 throw new ArgumentNullException("next");
40 Contract.EndContractBlock();
41 Contract.Assume(TaskScheduler.Current!=null);
43 var tcs = new TaskCompletionSource<T2>();
44 first.ContinueWith(delegate
46 if (first.IsFaulted) tcs.TrySetException(first.Exception.InnerExceptions);
47 else if (first.IsCanceled) tcs.TrySetCanceled();
52 var t = next(first.Result);
53 if (t == null) tcs.TrySetCanceled();
54 else t.ContinueWith(delegate
56 if (t.IsFaulted) tcs.TrySetException(t.Exception.InnerExceptions);
57 else if (t.IsCanceled) tcs.TrySetCanceled();
58 else tcs.TrySetResult(t.Result);
59 }, TaskContinuationOptions.ExecuteSynchronously);
61 catch (Exception exc) { tcs.TrySetException(exc); }
63 }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current);
67 public static Task Then<T1>(this Task<T1> first, Func<T1, Task> next, CancellationToken cancellationToken)
70 throw new ArgumentNullException("first");
72 throw new ArgumentNullException("next");
73 Contract.EndContractBlock();
74 Contract.Assume(TaskScheduler.Current != null);
76 var tcs = new TaskCompletionSource<object>();
77 first.ContinueWith(delegate
79 if (first.IsFaulted) tcs.TrySetException(first.Exception.InnerExceptions);
80 else if (first.IsCanceled) tcs.TrySetCanceled();
85 var t = next(first.Result);
86 if (t == null) tcs.TrySetCanceled();
87 else t.ContinueWith(delegate
89 if (t.IsFaulted) tcs.TrySetException(t.Exception.InnerExceptions);
90 else if (t.IsCanceled) tcs.TrySetCanceled();
91 else tcs.TrySetResult(null);
92 }, TaskContinuationOptions.ExecuteSynchronously);
94 catch (Exception exc) { tcs.TrySetException(exc); }
96 }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current);
102 public static void ReportExceptions(this Task task,Action<AggregateException> OnError,Action OnSuccess )
104 if (!task.IsCompleted) throw new InvalidOperationException("The task has not completed.");
106 task.Exception.Handle(exc=>
108 OnError(task.Exception);
117 public static bool TryRemove<T>(this ObservableConcurrentCollection<T> collection,T item) where T:class
119 IProducerConsumerCollection<T> items= collection;
120 for (var i = 0; i < items.Count; i++)
123 if (!items.TryTake(out tempItem))
125 if (tempItem == item)