annotate Implab/Promise.cs @ 266:254d1f255d87 v3

Добавлена метка v3.0.10 для набора изменений 74e048cbaac8
author cin
date Mon, 16 Apr 2018 19:45:18 +0300
parents 547a2fc0d93e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
1 using System;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
2 using System.Collections.Generic;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
3 using System.Diagnostics;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
4 using System.Reflection;
260
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
5 using System.Threading;
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
6 using System.Threading.Tasks;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
7 using Implab.Parallels;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
8
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
9 namespace Implab {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
10 public class Promise : AbstractEvent<IResolvable>, IPromise {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
11 public static IDispatcher DefaultDispatcher {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
12 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
13 return ThreadPoolDispatcher.Instance;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
14 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
15 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
16
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
17 class ResolvableSignal : IResolvable {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
18 public Signal Signal { get; private set; }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
19 public ResolvableSignal() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
20 Signal = new Signal();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
21 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
22
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
23
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
24 public void Reject(Exception error) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
25 Signal.Set();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
26 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
27
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
28 public void Resolve() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
29 Signal.Set();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
30 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
31 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
32
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
33 PromiseState m_state;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
34
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
35 Exception m_error;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
36
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
37 public bool IsRejected {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
38 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
39 return m_state == PromiseState.Rejected;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
40 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
41 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
42
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
43 public bool IsFulfilled {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
44 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
45 return m_state == PromiseState.Fulfilled;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
46 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
47 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
48
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
49 public Exception RejectReason {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
50 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
51 return m_error;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
52 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
53 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
54
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
55 internal Promise() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
56
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
57 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
58
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
59 internal void ResolvePromise() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
60 if (BeginTransit()) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
61 m_state = PromiseState.Fulfilled;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
62 CompleteTransit();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
63 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
64 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
65
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
66 internal void RejectPromise(Exception reason) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
67 if (BeginTransit()) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
68 m_error = reason;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
69 m_state = PromiseState.Rejected;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
70 CompleteTransit();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
71 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
72 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
73
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
74
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
75 #region implemented abstract members of AbstractPromise
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
76
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
77 protected override void SignalHandler(IResolvable handler) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
78 switch (m_state) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
79 case PromiseState.Fulfilled:
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
80 handler.Resolve();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
81 break;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
82 case PromiseState.Rejected:
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
83 handler.Reject(RejectReason);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
84 break;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
85 default:
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
86 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", m_state));
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
87 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
88 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
89
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
90 protected void WaitResult(int timeout) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
91 if (!(IsResolved || GetFulfillSignal().Wait(timeout)))
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
92 throw new TimeoutException();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
93 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
94
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
95 protected Signal GetFulfillSignal() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
96 var next = new ResolvableSignal();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
97 Then(next);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
98 return next.Signal;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
99 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
100
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
101 #endregion
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
102
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
103
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
104 public Type ResultType {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
105 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
106 return typeof(void);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
107 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
108 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
109
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
110
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
111 protected void Rethrow() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
112 Debug.Assert(m_error != null);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
113 if (m_error is OperationCanceledException)
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
114 throw new OperationCanceledException("Operation cancelled", m_error);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
115 else
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
116 throw new TargetInvocationException(m_error);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
117 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
118
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
119 public void Then(IResolvable next) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
120 AddHandler(next);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
121 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
122
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
123 public IPromise<T> Cast<T>() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
124 throw new InvalidCastException();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
125 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
126
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
127 public void Join() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
128 WaitResult(-1);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
129 if (IsRejected)
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
130 Rethrow();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
131 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
132
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
133 public void Join(int timeout) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
134 WaitResult(timeout);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
135 if (IsRejected)
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
136 Rethrow();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
137 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
138
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
139 public static ResolvedPromise Resolve() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
140 return new ResolvedPromise();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
141 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
142
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
143 public static ResolvedPromise<T> Resolve<T>(T result) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
144 return new ResolvedPromise<T>(result);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
145 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
146
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
147 public static RejectedPromise Reject(Exception reason) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
148 return new RejectedPromise(reason);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
149 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
150
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
151 public static RejectedPromise<T> Reject<T>(Exception reason) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
152 return new RejectedPromise<T>(reason);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
153 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
154
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
155 public static IPromise Create(PromiseExecutor executor) {
260
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
156 return Create(executor, CancellationToken.None);
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
157 }
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
158
260
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
159 public static IPromise Create(PromiseExecutor executor, CancellationToken ct) {
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
160 Safe.ArgumentNotNull(executor, nameof(executor));
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
161 if (!ct.CanBeCanceled)
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
162 return Create(executor);
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
163
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
164 var d = new Deferred();
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
165
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
166 ct.Register(d.Cancel);
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
167
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
168 try {
260
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
169 if (!ct.IsCancellationRequested)
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
170 executor(d);
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
171 } catch(Exception e) {
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
172 d.Reject(e);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
173 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
174 return d.Promise;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
175 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
176
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
177 public static IPromise<T> Create<T>(PromiseExecutor<T> executor) {
260
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
178 return Create(executor, CancellationToken.None);
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
179 }
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
180
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
181 public static IPromise<T> Create<T>(PromiseExecutor<T> executor, CancellationToken ct) {
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
182 Safe.ArgumentNotNull(executor, nameof(executor));
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
183
249
d82909310094 Implab.Test moved to xunit
cin
parents: 248
diff changeset
184 var d = new Deferred<T>();
260
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
185
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
186 ct.Register(d.Cancel);
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
187
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
188 try {
260
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
189 if (!ct.IsCancellationRequested)
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
190 executor(d);
547a2fc0d93e minor fixes
cin
parents: 249
diff changeset
191 } catch(Exception e) {
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
192 d.Reject(e);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
193 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
194 return d.Promise;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
195 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
196
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
197 public static IPromise All(IEnumerable<IPromise> promises) {
249
d82909310094 Implab.Test moved to xunit
cin
parents: 248
diff changeset
198 var d = new Deferred();
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
199 var all = new PromiseAll(d);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
200 foreach (var promise in promises) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
201 all.AddPromise(promise);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
202 if (all.Done)
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
203 break;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
204 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
205 all.Complete();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
206 return all.ResultPromise;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
207 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
208
249
d82909310094 Implab.Test moved to xunit
cin
parents: 248
diff changeset
209 public static IPromise<T[]> All<T>(IEnumerable<IPromise<T>> promises, Func<T, IPromise> cleanup = null, Action cancel = null) {
d82909310094 Implab.Test moved to xunit
cin
parents: 248
diff changeset
210 var d = new Deferred<T[]>();
248
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
211 var all = new PromiseAll<T>(d, cleanup, cancel);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
212 foreach (var promise in promises) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
213 all.AddPromise(promise);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
214 if (all.Done)
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
215 break;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
216 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
217 all.Complete();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
218 return all.ResultPromise;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
219 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
220 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
221 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
222