annotate Implab/Promise`1.cs @ 275:6fefd5811b9b v3

refactoring
author cin
date Fri, 27 Apr 2018 16:57:30 +0300
parents 5cb4826c2c2a
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.Diagnostics;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
3 using System.Reflection;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
4 using Implab.Parallels;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
5
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
6 namespace Implab {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
7 public class Promise<T> : AbstractEvent<IResolvable<T>>, IPromise<T> {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
8
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
9 class ResolvableSignal : IResolvable<T> {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
10 public Signal Signal { get; private set; }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
11 public ResolvableSignal() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
12 Signal = new Signal();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
13 }
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 public void Reject(Exception error) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
17 Signal.Set();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
18 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
19
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
20 public void Resolve(T result) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
21 Signal.Set();
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
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
25 class ResolvableWrapper : IResolvable<T> {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
26 readonly IResolvable m_resolvable;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
27 public ResolvableWrapper(IResolvable resolvable) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
28 m_resolvable = resolvable;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
29 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
30
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
31 public void Reject(Exception reason) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
32 m_resolvable.Reject(reason);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
33 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
34
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
35 public void Resolve(T value) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
36 m_resolvable.Resolve();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
37 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
38 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
39
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
40 PromiseState m_state;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
41
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
42 T m_result;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
43
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
44 Exception m_error;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
45
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
46 public bool IsRejected {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
47 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
48 return m_state == PromiseState.Rejected;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
49 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
50 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
51
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
52 public bool IsFulfilled {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
53 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
54 return m_state == PromiseState.Fulfilled;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
55 }
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 public Exception RejectReason {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
59 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
60 return m_error;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
61 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
62 }
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 internal void ResolvePromise(T result) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
66 if (BeginTransit()) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
67 m_result = result;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
68 m_state = PromiseState.Fulfilled;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
69 CompleteTransit();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
70 }
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 internal void RejectPromise(Exception reason) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
74 if (BeginTransit()) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
75 m_error = reason;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
76 m_state = PromiseState.Rejected;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
77 CompleteTransit();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
78 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
79 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
80
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
81
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
82 #region implemented abstract members of AbstractPromise
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
83
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
84 protected override void SignalHandler(IResolvable<T> handler) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
85 switch (m_state) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
86 case PromiseState.Fulfilled:
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
87 handler.Resolve(m_result);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
88 break;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
89 case PromiseState.Rejected:
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
90 handler.Reject(RejectReason);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
91 break;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
92 default:
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
93 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", m_state));
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
94 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
95 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
96
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
97 protected void WaitResult(int timeout) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
98 if (!(IsResolved || GetFulfillSignal().Wait(timeout)))
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
99 throw new TimeoutException();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
100 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
101
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
102 protected Signal GetFulfillSignal() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
103 var next = new ResolvableSignal();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
104 Then(next);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
105 return next.Signal;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
106 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
107
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
108 #endregion
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
109
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
110 public Type ResultType {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
111 get {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
112 return typeof(void);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
113 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
114 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
115
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
116
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
117 protected void Rethrow() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
118 if (m_error is OperationCanceledException)
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
119 throw new OperationCanceledException("Operation cancelled", m_error);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
120 else
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
121 throw new TargetInvocationException(m_error);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
122 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
123
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
124 public void Then(IResolvable<T> next) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
125 AddHandler(next);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
126 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
127
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
128 public void Then(IResolvable next) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
129 AddHandler(new ResolvableWrapper(next));
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
130 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
131
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
132 public IPromise<T2> Cast<T2>() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
133 return (IPromise<T2>)this;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
134 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
135
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
136 void IPromise.Join() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
137 Join();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
138 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
139
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
140 void IPromise.Join(int timeout) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
141 Join(timeout);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
142 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
143
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
144 public T Join() {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
145 WaitResult(-1);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
146 if (IsRejected)
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
147 Rethrow();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
148 return m_result;
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 T Join(int timeout) {
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
152 WaitResult(timeout);
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
153 if (IsRejected)
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
154 Rethrow();
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
155 return m_result;
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
156 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
157 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
158 }
5cb4826c2c2a Added awaiters to promises
cin
parents:
diff changeset
159