72
|
1 using System.Threading;
|
75
|
2 using System;
|
109
|
3 using Implab.Diagnostics;
|
|
4
|
|
5
|
75
|
6 #if NET_4_5
|
|
7 using System.Threading.Tasks;
|
|
8 #endif
|
72
|
9
|
|
10 namespace Implab {
|
|
11 public static class PromiseExtensions {
|
|
12 public static IPromise<T> DispatchToCurrentContext<T>(this IPromise<T> that) {
|
75
|
13 Safe.ArgumentNotNull(that, "that");
|
72
|
14 var context = SynchronizationContext.Current;
|
|
15 if (context == null)
|
|
16 return that;
|
|
17
|
101
|
18 var p = new SyncContextPromise<T>(context, that);
|
72
|
19
|
104
|
20 that.On(
|
76
|
21 p.Resolve,
|
|
22 p.Reject,
|
|
23 p.Cancel
|
72
|
24 );
|
|
25 return p;
|
|
26 }
|
|
27
|
|
28 public static IPromise<T> DispatchToContext<T>(this IPromise<T> that, SynchronizationContext context) {
|
75
|
29 Safe.ArgumentNotNull(that, "that");
|
72
|
30 Safe.ArgumentNotNull(context, "context");
|
|
31
|
101
|
32 var p = new SyncContextPromise<T>(context, that);
|
72
|
33
|
104
|
34 that.On(
|
76
|
35 p.Resolve,
|
|
36 p.Reject,
|
|
37 p.Cancel
|
72
|
38 );
|
|
39 return p;
|
|
40 }
|
75
|
41
|
101
|
42 /// <summary>
|
|
43 /// Ensures the dispatched.
|
|
44 /// </summary>
|
|
45 /// <returns>The dispatched.</returns>
|
|
46 /// <param name="that">That.</param>
|
|
47 /// <param name="head">Head.</param>
|
|
48 /// <param name="cleanup">Cleanup.</param>
|
|
49 /// <typeparam name="TPromise">The 1st type parameter.</typeparam>
|
|
50 /// <typeparam name="T">The 2nd type parameter.</typeparam>
|
|
51 public static TPromise EnsureDispatched<TPromise,T>(this TPromise that, IPromise<T> head, Action<T> cleanup) where TPromise : IPromise{
|
|
52 Safe.ArgumentNotNull(that, "that");
|
|
53 Safe.ArgumentNotNull(head, "head");
|
|
54
|
104
|
55 that.On(null,null,() => head.On(cleanup));
|
101
|
56
|
|
57 return that;
|
|
58 }
|
|
59
|
75
|
60 public static AsyncCallback AsyncCallback<T>(this Promise<T> that, Func<IAsyncResult,T> callback) {
|
|
61 Safe.ArgumentNotNull(that, "that");
|
|
62 Safe.ArgumentNotNull(callback, "callback");
|
109
|
63 var op = TraceContext.Instance.CurrentOperation;
|
75
|
64 return ar => {
|
109
|
65 TraceContext.Instance.EnterLogicalOperation(op,false);
|
75
|
66 try {
|
|
67 that.Resolve(callback(ar));
|
|
68 } catch (Exception err) {
|
|
69 that.Reject(err);
|
109
|
70 } finally {
|
|
71 TraceContext.Instance.Leave();
|
75
|
72 }
|
|
73 };
|
|
74 }
|
110
|
75
|
|
76 static void CancelCallback(object cookie) {
|
|
77 ((ICancellable)cookie).Cancel();
|
|
78 }
|
|
79
|
|
80 /// <summary>
|
|
81 /// Cancells promise after the specified timeout is elapsed.
|
|
82 /// </summary>
|
|
83 /// <param name="that">The promise to cancel on timeout.</param>
|
|
84 /// <param name="milliseconds">The timeout in milliseconds.</param>
|
|
85 /// <typeparam name="TPromise">The 1st type parameter.</typeparam>
|
|
86 public static TPromise Timeout<TPromise>(this TPromise that, int milliseconds) where TPromise : IPromise {
|
|
87 Safe.ArgumentNotNull(that, "that");
|
|
88 var timer = new Timer(CancelCallback, that, milliseconds, -1);
|
|
89 that.On(timer.Dispose, PromiseEventType.All);
|
|
90 return that;
|
|
91 }
|
75
|
92
|
|
93 #if NET_4_5
|
|
94
|
|
95 public static Task<T> GetTask<T>(this IPromise<T> that) {
|
|
96 Safe.ArgumentNotNull(that, "that");
|
|
97 var tcs = new TaskCompletionSource<T>();
|
|
98
|
104
|
99 that.On(tcs.SetResult, tcs.SetException, tcs.SetCanceled);
|
75
|
100
|
|
101 return tcs.Task;
|
|
102 }
|
|
103
|
|
104 #endif
|
72
|
105 }
|
|
106 }
|
|
107
|