##// END OF EJS Templates
PollingComponent: implemented correct stopping
cin -
r259:7d52dc684bbd v3
parent child
Show More
@@ -0,0 +1,42
1 using System;
2 using System.Threading;
3 using System.Threading.Tasks;
4 using Implab.Components;
5 using Xunit;
6
7 namespace Implab.Test
8 {
9 class TimeLog : PollingComponent {
10 public TimeLog() : base(true) {
11 }
12
13 protected override Task Poll(CancellationToken ct) {
14 Console.WriteLine("Poll");
15 return Task.CompletedTask;
16 }
17 }
18
19 public class UnitTest1
20 {
21 [Fact]
22 public async Task Test1()
23 {
24
25 using(var tl = new TimeLog()) {
26 tl.StateChanged += (self, args) => Console.WriteLine("{0}", args.State);
27 tl.Delay = 1000;
28 tl.Interval = 500;
29
30
31 tl.Start(CancellationToken.None);
32 await tl.Completion;
33
34 await Task.Delay(2000);
35
36 tl.Stop(CancellationToken.None);
37 await tl.Completion;
38 await Task.Delay(3000);
39 }
40 }
41 }
42 }
@@ -1,17 +1,17
1 <Project Sdk="Microsoft.NET.Sdk">
1 <Project Sdk="Microsoft.NET.Sdk">
2
2
3 <PropertyGroup>
3 <PropertyGroup>
4 <TargetFramework>net46</TargetFramework>
4 <TargetFramework>netcoreapp2.1</TargetFramework>
5 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46' and '$(OSTYPE)'=='linux'">/usr/lib/mono/4.5/</FrameworkPathOverride>
6
5
7 <IsPackable>false</IsPackable>
6 <IsPackable>false</IsPackable>
8 </PropertyGroup>
7 </PropertyGroup>
8
9 <ItemGroup>
9 <ItemGroup>
10 <ProjectReference Include="../Implab/Implab.csproj" />
10 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0-preview-20180109-01" />
11 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
12 <PackageReference Include="xunit" Version="2.3.1" />
11 <PackageReference Include="xunit" Version="2.3.1" />
13 <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
12 <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
13 <ProjectReference Include="../Implab/Implab.csproj"/>
14 <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
14 <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
15 </ItemGroup>
15 </ItemGroup>
16
16
17 </Project>
17 </Project>
@@ -1,73 +1,89
1 using System;
1 using System;
2 using System.Threading;
2 using System.Threading;
3 using System.Threading.Tasks;
3 using System.Threading.Tasks;
4
4
5 namespace Implab.Components {
5 namespace Implab.Components {
6 public abstract class PollingComponent : RunnableComponent {
6 public abstract class PollingComponent : RunnableComponent {
7
7
8 readonly Timer m_timer;
8 readonly Timer m_timer;
9
9
10 readonly CancellationTokenSource m_cancellation = new CancellationTokenSource();
10 readonly CancellationTokenSource m_cancellation = new CancellationTokenSource();
11
11
12 Task m_pending;
13 Task m_poll;
14
12 /// <summary>
15 /// <summary>
13 /// Poll interval in milliseconds.
16 /// Poll interval in milliseconds.
14 /// </summary>
17 /// </summary>
15 /// <returns></returns>
18 /// <returns></returns>
16 public int Interval { get; set; }
19 public int Interval { get; set; }
17
20
18 /// <summary>
21 /// <summary>
19 /// Delay to the first poll after start in milliseconds
22 /// Delay to the first poll after start in milliseconds
20 /// </summary>
23 /// </summary>
21 /// <returns></returns>
24 /// <returns></returns>
22 public int Delay { get; set; }
25 public int Delay { get; set; }
23
26
24 /// <summary>
27 /// <summary>
25 /// Indicates how to handle unhandled exceptions in <see cref="Poll()"/> method.
28 /// Indicates how to handle unhandled exceptions in <see cref="Poll()"/> method.
26 /// </summary>
29 /// </summary>
27 /// <returns></returns>
30 /// <returns></returns>
28 public bool FailOnError { get; set; }
31 public bool FailOnError { get; set; }
29
32
30 /// <summary>
33 /// <summary>
31 /// Event for the unhandled exceptions in <see cref="Poll()"/> method.
34 /// Event for the unhandled exceptions in <see cref="Poll()"/> method.
32 /// </summary>
35 /// </summary>
33 public event EventHandler<UnhandledExceptionEventArgs> UnhandledException;
36 public event EventHandler<UnhandledExceptionEventArgs> UnhandledException;
34
37
35 protected PollingComponent(bool initialized) : base(initialized) {
38 protected PollingComponent(bool initialized) : base(initialized) {
36 m_timer = new Timer(OnTimer);
39 m_timer = new Timer(OnTimer);
37 }
40 }
38
41
39 protected override void RunInternal() {
42 protected override void RunInternal() {
40 ScheduleNextPoll(Delay);
43 ScheduleNextPoll(Delay);
41 }
44 }
42
45
43
46
44 //TODO override stop
47 protected override async Task StopInternalAsync(CancellationToken ct) {
48 // component in Stopping state, no new polls will be scheduled
49 m_cancellation.Cancel();
50 try {
51 // await for pending poll
52 await m_poll;
53 } catch (OperationCanceledException e) {
54 // OK
55 }
56 }
45
57
46 protected abstract Task Poll(CancellationToken ct);
58 protected abstract Task Poll(CancellationToken ct);
47
59
48 void ScheduleNextPoll(int timeout) {
60 void ScheduleNextPoll(int timeout) {
49 lock (SynchronizationObject) {
61 lock (SynchronizationObject) {
50 if (State == ExecutionState.Running)
62 if (State == ExecutionState.Running) {
63 m_pending = Safe.CreateTask(m_cancellation.Token);
64 m_poll = m_pending.Then(() => Poll(m_cancellation.Token));
51 m_timer.Change(timeout, Timeout.Infinite);
65 m_timer.Change(timeout, Timeout.Infinite);
52 }
66 }
53 }
67 }
68 }
54
69
55 void OnTimer(object state) {
70 async void OnTimer(object state) {
56 try {
71 try {
57 Poll(m_cancellation.Token);
72 m_pending.Start();
73 await m_poll;
58 } catch (Exception e) {
74 } catch (Exception e) {
59 UnhandledException.DispatchEvent(this, new UnhandledExceptionEventArgs(e, false));
75 UnhandledException.DispatchEvent(this, new UnhandledExceptionEventArgs(e, false));
60 if (FailOnError)
76 if (FailOnError)
61 Fail(e);
77 Fail(e);
62 }
78 }
63 ScheduleNextPoll(Interval);
79 ScheduleNextPoll(Interval);
64 }
80 }
65
81
66 protected override void Dispose(bool disposing) {
82 protected override void Dispose(bool disposing) {
67 if (disposing)
83 if (disposing)
68 Safe.Dispose(m_timer, m_cancellation);
84 Safe.Dispose(m_timer, m_cancellation);
69 base.Dispose(disposing);
85 base.Dispose(disposing);
70 }
86 }
71
87
72 }
88 }
73 } No newline at end of file
89 }
@@ -1,217 +1,226
1 using System.Threading;
1 using System.Threading;
2 using System;
2 using System;
3 using Implab.Diagnostics;
3 using Implab.Diagnostics;
4 using System.Collections.Generic;
4 using System.Collections.Generic;
5 using System.Linq;
5 using System.Linq;
6
6
7 namespace Implab {
7 namespace Implab {
8 public static class PromiseExtensions {
8 public static class PromiseExtensions {
9
9
10 public static IPromise Then(this IPromise that, Action fulfilled, Action<Exception> rejected) {
10 public static IPromise Then(this IPromise that, Action fulfilled, Action<Exception> rejected) {
11 var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher);
11 var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher);
12 that.Then(reaction);
12 that.Then(reaction);
13 return reaction.Promise;
13 return reaction.Promise;
14 }
14 }
15
15
16 public static IPromise Then(this IPromise that, Action fulfilled) {
16 public static IPromise Then(this IPromise that, Action fulfilled) {
17 var reaction = PromiseActionReaction.Create(fulfilled, null, Promise.DefaultDispatcher);
17 var reaction = PromiseActionReaction.Create(fulfilled, null, Promise.DefaultDispatcher);
18 that.Then(reaction);
18 that.Then(reaction);
19 return reaction.Promise;
19 return reaction.Promise;
20 }
20 }
21
21
22 public static IPromise Then(this IPromise that, Action fulfilled, Func<Exception, IPromise> rejected) {
22 public static IPromise Then(this IPromise that, Action fulfilled, Func<Exception, IPromise> rejected) {
23 var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher);
23 var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher);
24 that.Then(reaction);
24 that.Then(reaction);
25 return reaction.Promise;
25 return reaction.Promise;
26 }
26 }
27
27
28 public static IPromise Then(this IPromise that, Func<IPromise> fulfilled, Action<Exception> rejected) {
28 public static IPromise Then(this IPromise that, Func<IPromise> fulfilled, Action<Exception> rejected) {
29 var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher);
29 var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher);
30 that.Then(reaction);
30 that.Then(reaction);
31 return reaction.Promise;
31 return reaction.Promise;
32 }
32 }
33
33
34 public static IPromise Then(this IPromise that, Func<IPromise> fulfilled) {
34 public static IPromise Then(this IPromise that, Func<IPromise> fulfilled) {
35 var reaction = PromiseActionReaction.Create(fulfilled, null, Promise.DefaultDispatcher);
35 var reaction = PromiseActionReaction.Create(fulfilled, null, Promise.DefaultDispatcher);
36 that.Then(reaction);
36 that.Then(reaction);
37 return reaction.Promise;
37 return reaction.Promise;
38 }
38 }
39
39
40 public static IPromise Then(this IPromise that, Func<IPromise> fulfilled, Func<Exception, IPromise> rejected) {
40 public static IPromise Then(this IPromise that, Func<IPromise> fulfilled, Func<Exception, IPromise> rejected) {
41 var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher);
41 var reaction = PromiseActionReaction.Create(fulfilled, rejected, Promise.DefaultDispatcher);
42 that.Then(reaction);
42 that.Then(reaction);
43 return reaction.Promise;
43 return reaction.Promise;
44 }
44 }
45
45
46 public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled, Action<Exception> rejected) {
46 public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled, Action<Exception> rejected) {
47 var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
47 var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
48 that.Then(reaction);
48 that.Then(reaction);
49 return reaction.Promise;
49 return reaction.Promise;
50 }
50 }
51
51
52 public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled) {
52 public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled) {
53 var reaction = PromiseActionReaction<T>.Create(fulfilled, null, Promise.DefaultDispatcher);
53 var reaction = PromiseActionReaction<T>.Create(fulfilled, null, Promise.DefaultDispatcher);
54 that.Then(reaction);
54 that.Then(reaction);
55 return reaction.Promise;
55 return reaction.Promise;
56 }
56 }
57
57
58 public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled, Func<Exception, IPromise> rejected) {
58 public static IPromise Then<T>(this IPromise<T> that, Action<T> fulfilled, Func<Exception, IPromise> rejected) {
59 var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
59 var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
60 that.Then(reaction);
60 that.Then(reaction);
61 return reaction.Promise;
61 return reaction.Promise;
62 }
62 }
63
63
64 public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled, Action<Exception> rejected) {
64 public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled, Action<Exception> rejected) {
65 var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
65 var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
66 that.Then(reaction);
66 that.Then(reaction);
67 return reaction.Promise;
67 return reaction.Promise;
68 }
68 }
69
69
70 public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled) {
70 public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled) {
71 var reaction = PromiseActionReaction<T>.Create(fulfilled, null, Promise.DefaultDispatcher);
71 var reaction = PromiseActionReaction<T>.Create(fulfilled, null, Promise.DefaultDispatcher);
72 that.Then(reaction);
72 that.Then(reaction);
73 return reaction.Promise;
73 return reaction.Promise;
74 }
74 }
75
75
76 public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled, Func<Exception, IPromise> rejected) {
76 public static IPromise Then<T>(this IPromise<T> that, Func<T, IPromise> fulfilled, Func<Exception, IPromise> rejected) {
77 var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
77 var reaction = PromiseActionReaction<T>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
78 that.Then(reaction);
78 that.Then(reaction);
79 return reaction.Promise;
79 return reaction.Promise;
80 }
80 }
81
81
82 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled, Func<Exception, Tout> rejected) {
82 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled, Func<Exception, Tout> rejected) {
83 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
83 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
84 that.Then(reaction);
84 that.Then(reaction);
85 return reaction.Promise;
85 return reaction.Promise;
86 }
86 }
87
87
88 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled) {
88 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled) {
89 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher);
89 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher);
90 that.Then(reaction);
90 that.Then(reaction);
91 return reaction.Promise;
91 return reaction.Promise;
92 }
92 }
93
93
94 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled, Func<Exception, IPromise<Tout>> rejected) {
94 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<Tout> fulfilled, Func<Exception, IPromise<Tout>> rejected) {
95 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
95 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
96 that.Then(reaction);
96 that.Then(reaction);
97 return reaction.Promise;
97 return reaction.Promise;
98 }
98 }
99
99
100 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled, Func<Exception, Tout> rejected) {
100 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled, Func<Exception, Tout> rejected) {
101 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
101 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
102 that.Then(reaction);
102 that.Then(reaction);
103 return reaction.Promise;
103 return reaction.Promise;
104 }
104 }
105
105
106 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled) {
106 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled) {
107 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher);
107 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher);
108 that.Then(reaction);
108 that.Then(reaction);
109 return reaction.Promise;
109 return reaction.Promise;
110 }
110 }
111
111
112 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled, Func<Exception, IPromise<Tout>> rejected) {
112 public static IPromise<Tout> Then<Tout>(this IPromise that, Func<IPromise<Tout>> fulfilled, Func<Exception, IPromise<Tout>> rejected) {
113 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
113 var reaction = PromiseFuncReaction<Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
114 that.Then(reaction);
114 that.Then(reaction);
115 return reaction.Promise;
115 return reaction.Promise;
116 }
116 }
117
117
118 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled, Func<Exception, Tout> rejected) {
118 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled, Func<Exception, Tout> rejected) {
119 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
119 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
120 that.Then(reaction);
120 that.Then(reaction);
121 return reaction.Promise;
121 return reaction.Promise;
122 }
122 }
123
123
124 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled) {
124 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled) {
125 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher);
125 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher);
126 that.Then(reaction);
126 that.Then(reaction);
127 return reaction.Promise;
127 return reaction.Promise;
128 }
128 }
129
129
130 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled, Func<Exception, IPromise<Tout>> rejected) {
130 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, Tout> fulfilled, Func<Exception, IPromise<Tout>> rejected) {
131 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
131 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
132 that.Then(reaction);
132 that.Then(reaction);
133 return reaction.Promise;
133 return reaction.Promise;
134 }
134 }
135
135
136 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled, Func<Exception, Tout> rejected) {
136 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled, Func<Exception, Tout> rejected) {
137 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
137 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
138 that.Then(reaction);
138 that.Then(reaction);
139 return reaction.Promise;
139 return reaction.Promise;
140 }
140 }
141
141
142 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled) {
142 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled) {
143 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher);
143 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, (Func<Exception, Tout>)null, Promise.DefaultDispatcher);
144 that.Then(reaction);
144 that.Then(reaction);
145 return reaction.Promise;
145 return reaction.Promise;
146 }
146 }
147
147
148 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled, Func<Exception, IPromise<Tout>> rejected) {
148 public static IPromise<Tout> Then<Tin, Tout>(this IPromise<Tin> that, Func<Tin, IPromise<Tout>> fulfilled, Func<Exception, IPromise<Tout>> rejected) {
149 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
149 var reaction = PromiseFuncReaction<Tin, Tout>.Create(fulfilled, rejected, Promise.DefaultDispatcher);
150 that.Then(reaction);
150 that.Then(reaction);
151 return reaction.Promise;
151 return reaction.Promise;
152 }
152 }
153
153
154 public static IPromise Catch(this IPromise that, Action<Exception> rejected) {
154 public static IPromise Catch(this IPromise that, Action<Exception> rejected) {
155 return Then(that, null, rejected);
155 return Then(that, null, rejected);
156 }
156 }
157
157
158 public static IPromise Catch(this IPromise that, Func<Exception, IPromise> rejected) {
158 public static IPromise Catch(this IPromise that, Func<Exception, IPromise> rejected) {
159 return Then(that, null, rejected);
159 return Then(that, null, rejected);
160 }
160 }
161
161
162 public static IPromise<Tout> Catch<Tout>(this IPromise that, Func<Exception, Tout> rejected) {
162 public static IPromise<Tout> Catch<Tout>(this IPromise that, Func<Exception, Tout> rejected) {
163 return Then(that, (Func<Tout>)null, rejected);
163 return Then(that, (Func<Tout>)null, rejected);
164 }
164 }
165
165
166 public static IPromise<Tout> Catch<Tout>(this IPromise that, Func<Exception, IPromise<Tout>> rejected) {
166 public static IPromise<Tout> Catch<Tout>(this IPromise that, Func<Exception, IPromise<Tout>> rejected) {
167 return Then(that, (Func<Tout>)null, rejected);
167 return Then(that, (Func<Tout>)null, rejected);
168 }
168 }
169
169
170 public static IPromise<Tout> Catch<Tin, Tout>(this IPromise<Tin> that, Func<Exception, Tout> rejected) {
170 public static IPromise<Tout> Catch<Tin, Tout>(this IPromise<Tin> that, Func<Exception, Tout> rejected) {
171 return Then(that, (Func<Tin, Tout>)null, rejected);
171 return Then(that, (Func<Tin, Tout>)null, rejected);
172 }
172 }
173
173
174 public static IPromise<Tout> Catch<Tin, Tout>(this IPromise<Tin> that, Func<Exception, IPromise<Tout>> rejected) {
174 public static IPromise<Tout> Catch<Tin, Tout>(this IPromise<Tin> that, Func<Exception, IPromise<Tout>> rejected) {
175 return Then(that, (Func<Tin, Tout>)null, rejected);
175 return Then(that, (Func<Tin, Tout>)null, rejected);
176 }
176 }
177
177
178 public static IPromise Finally(this IPromise that, Action final) {
178 public static IPromise Finally(this IPromise that, Action final) {
179 return Then(that, final, e => {
179 return Then(that, final, e => {
180 final();
180 final();
181 throw e.Rethrow();
181 throw e.Rethrow();
182 });
182 });
183 }
183 }
184
184
185 public static IPromise Finally(this IPromise that, Func<IPromise> final) {
185 public static IPromise Finally(this IPromise that, Func<IPromise> final) {
186 return Then(that, final, e => {
186 return Then(that, final, e => {
187 final();
187 final();
188 throw e.Rethrow();
188 throw e.Rethrow();
189 });
189 });
190 }
190 }
191
191
192 public static IPromise<T> Finally<T>(this IPromise<T> that, Action final) {
192 public static IPromise<T> Finally<T>(this IPromise<T> that, Action final) {
193 return Then<T, T>(that, x => {
193 return Then<T, T>(that, x => {
194 final();
194 final();
195 return x;
195 return x;
196 }, new Func<Exception, T>(e => {
196 }, new Func<Exception, T>(e => {
197 final();
197 final();
198 throw e.Rethrow();
198 throw e.Rethrow();
199 }));
199 }));
200 }
200 }
201
201
202 public static IPromise<T> Finally<T>(this IPromise<T> that, Func<IPromise> final) {
202 public static IPromise<T> Finally<T>(this IPromise<T> that, Func<IPromise> final) {
203 return Then<T, T>(that, x => {
203 return Then<T, T>(that, x => {
204 return final()
204 return final()
205 .Then(() => x);
205 .Then(() => x);
206 }, new Func<Exception, IPromise<T>>(e => {
206 }, new Func<Exception, IPromise<T>>(e => {
207 return final()
207 return final()
208 .Then(new Func<T>(() => {
208 .Then(new Func<T>(() => {
209 throw e.Rethrow();
209 throw e.Rethrow();
210 }));
210 }));
211 }));
211 }));
212 }
212 }
213
213
214 public static PromiseAwaiter GetAwaiter(this IPromise that) {
215 Safe.ArgumentNotNull(that, nameof(that));
216 return new PromiseAwaiter(that);
217 }
218
219 public static PromiseAwaiter<T> GetAwaiter<T>(this IPromise<T> that) {
220 Safe.ArgumentNotNull(that, nameof(that));
221 return new PromiseAwaiter<T>(that);
222 }
214
223
215 }
224 }
216 }
225 }
217
226
@@ -1,171 +1,182
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4 using System.Text;
4 using System.Text;
5 using System.Text.RegularExpressions;
5 using System.Text.RegularExpressions;
6 using System.Diagnostics;
6 using System.Diagnostics;
7 using System.Collections;
7 using System.Collections;
8 using System.Runtime.CompilerServices;
8 using System.Runtime.CompilerServices;
9 using System.Threading.Tasks;
9 using System.Threading.Tasks;
10 using System.Threading;
10
11
11 #if NET_4_5
12 #if NET_4_5
12 using System.Threading.Tasks;
13 using System.Threading.Tasks;
13 #endif
14 #endif
14
15
15 namespace Implab
16 namespace Implab
16 {
17 {
17 public static class Safe
18 public static class Safe
18 {
19 {
19 [MethodImpl(MethodImplOptions.AggressiveInlining)]
20 [MethodImpl(MethodImplOptions.AggressiveInlining)]
20 public static void ArgumentAssert(bool condition, string paramName) {
21 public static void ArgumentAssert(bool condition, string paramName) {
21 if (!condition)
22 if (!condition)
22 throw new ArgumentException("The parameter is invalid", paramName);
23 throw new ArgumentException("The parameter is invalid", paramName);
23 }
24 }
24
25
25 [MethodImpl(MethodImplOptions.AggressiveInlining)]
26 [MethodImpl(MethodImplOptions.AggressiveInlining)]
26 public static void ArgumentMatch(string value, string paramName, Regex rx) {
27 public static void ArgumentMatch(string value, string paramName, Regex rx) {
27 if (rx == null)
28 if (rx == null)
28 throw new ArgumentNullException("rx");
29 throw new ArgumentNullException("rx");
29 if (!rx.IsMatch(value))
30 if (!rx.IsMatch(value))
30 throw new ArgumentException(String.Format("The prameter value must match {0}", rx), paramName);
31 throw new ArgumentException(String.Format("The prameter value must match {0}", rx), paramName);
31 }
32 }
32
33
33 [MethodImpl(MethodImplOptions.AggressiveInlining)]
34 [MethodImpl(MethodImplOptions.AggressiveInlining)]
34 public static void ArgumentNotEmpty(string value, string paramName) {
35 public static void ArgumentNotEmpty(string value, string paramName) {
35 if (String.IsNullOrEmpty(value))
36 if (String.IsNullOrEmpty(value))
36 throw new ArgumentException("The parameter can't be empty", paramName);
37 throw new ArgumentException("The parameter can't be empty", paramName);
37 }
38 }
38
39
39 [MethodImpl(MethodImplOptions.AggressiveInlining)]
40 [MethodImpl(MethodImplOptions.AggressiveInlining)]
40 public static void ArgumentNotEmpty<T>(T[] value, string paramName) {
41 public static void ArgumentNotEmpty<T>(T[] value, string paramName) {
41 if (value == null || value.Length == 0)
42 if (value == null || value.Length == 0)
42 throw new ArgumentException("The array must be not emty", paramName);
43 throw new ArgumentException("The array must be not emty", paramName);
43 }
44 }
44
45
45 [MethodImpl(MethodImplOptions.AggressiveInlining)]
46 [MethodImpl(MethodImplOptions.AggressiveInlining)]
46 public static void ArgumentNotNull(object value, string paramName) {
47 public static void ArgumentNotNull(object value, string paramName) {
47 if (value == null)
48 if (value == null)
48 throw new ArgumentNullException(paramName);
49 throw new ArgumentNullException(paramName);
49 }
50 }
50
51
51 [MethodImpl(MethodImplOptions.AggressiveInlining)]
52 [MethodImpl(MethodImplOptions.AggressiveInlining)]
52 internal static void ArgumentGreaterEqThan(int value, int min, string paramName) {
53 internal static void ArgumentGreaterEqThan(int value, int min, string paramName) {
53 if (value < min)
54 if (value < min)
54 throw new ArgumentOutOfRangeException(paramName);
55 throw new ArgumentOutOfRangeException(paramName);
55 }
56 }
56
57
57 [MethodImpl(MethodImplOptions.AggressiveInlining)]
58 [MethodImpl(MethodImplOptions.AggressiveInlining)]
58 public static void ArgumentInRange(bool condition, string paramName) {
59 public static void ArgumentInRange(bool condition, string paramName) {
59 if (!condition)
60 if (!condition)
60 throw new ArgumentOutOfRangeException(paramName);
61 throw new ArgumentOutOfRangeException(paramName);
61 }
62 }
62
63
63 [MethodImpl(MethodImplOptions.AggressiveInlining)]
64 [MethodImpl(MethodImplOptions.AggressiveInlining)]
64 public static void ArgumentOfType(object value, Type type, string paramName) {
65 public static void ArgumentOfType(object value, Type type, string paramName) {
65 if (!type.IsInstanceOfType(value))
66 if (!type.IsInstanceOfType(value))
66 throw new ArgumentException(String.Format("The parameter must be of type {0}", type), paramName);
67 throw new ArgumentException(String.Format("The parameter must be of type {0}", type), paramName);
67 }
68 }
68
69
69 public static void Dispose(params IDisposable[] objects) {
70 public static void Dispose(params IDisposable[] objects) {
70 foreach (var d in objects)
71 foreach (var d in objects)
71 if (d != null)
72 if (d != null)
72 d.Dispose();
73 d.Dispose();
73 }
74 }
74
75
75 public static void Dispose(params object[] objects) {
76 public static void Dispose(params object[] objects) {
76 foreach (var obj in objects) {
77 foreach (var obj in objects) {
77 var d = obj as IDisposable;
78 var d = obj as IDisposable;
78 if (d != null)
79 if (d != null)
79 d.Dispose();
80 d.Dispose();
80 }
81 }
81 }
82 }
82
83
83 public static void DisposeCollection(IEnumerable<IDisposable> objects) {
84 public static void DisposeCollection(IEnumerable<IDisposable> objects) {
84 foreach (var d in objects)
85 foreach (var d in objects)
85 Dispose(d);
86 Dispose(d);
86 }
87 }
87
88
88 public static void DisposeCollection(IEnumerable objects) {
89 public static void DisposeCollection(IEnumerable objects) {
89 foreach (var d in objects)
90 foreach (var d in objects)
90 Dispose(d);
91 Dispose(d);
91 }
92 }
92
93
93 public static void Dispose(object obj) {
94 public static void Dispose(object obj) {
94 if (obj is IDisposable)
95 if (obj is IDisposable)
95 Dispose((IDisposable)obj);
96 Dispose((IDisposable)obj);
96
97
97 }
98 }
98
99
99 [DebuggerStepThrough]
100 [DebuggerStepThrough]
100 public static void DispatchEvent<T>(this EventHandler<T> handler, object sender, T args) {
101 public static void DispatchEvent<T>(this EventHandler<T> handler, object sender, T args) {
101 if (handler != null)
102 if (handler != null)
102 handler(sender, args);
103 handler(sender, args);
103 }
104 }
104
105
105 [DebuggerStepThrough]
106 [DebuggerStepThrough]
106 public static void DispatchEvent(this EventHandler handler, object sender, EventArgs args) {
107 public static void DispatchEvent(this EventHandler handler, object sender, EventArgs args) {
107 if (handler != null)
108 if (handler != null)
108 handler(sender, args);
109 handler(sender, args);
109 }
110 }
110
111
111 [DebuggerStepThrough]
112 [DebuggerStepThrough]
112 public static IPromise<T> Run<T>(Func<T> action) {
113 public static IPromise<T> Run<T>(Func<T> action) {
113 ArgumentNotNull(action, "action");
114 ArgumentNotNull(action, "action");
114
115
115 try {
116 try {
116 return Promise.Resolve(action());
117 return Promise.Resolve(action());
117 } catch (Exception err) {
118 } catch (Exception err) {
118 return Promise.Reject<T>(err);
119 return Promise.Reject<T>(err);
119 }
120 }
120 }
121 }
121
122
122 [DebuggerStepThrough]
123 [DebuggerStepThrough]
123 public static IPromise Run(Action action) {
124 public static IPromise Run(Action action) {
124 ArgumentNotNull(action, "action");
125 ArgumentNotNull(action, "action");
125
126
126 try {
127 try {
127 action();
128 action();
128 return Promise.Resolve();
129 return Promise.Resolve();
129 } catch (Exception err) {
130 } catch (Exception err) {
130 return Promise.Reject(err);
131 return Promise.Reject(err);
131 }
132 }
132 }
133 }
133
134
134 [DebuggerStepThrough]
135 [DebuggerStepThrough]
135 public static IPromise Run(Func<IPromise> action) {
136 public static IPromise Run(Func<IPromise> action) {
136 ArgumentNotNull(action, "action");
137 ArgumentNotNull(action, "action");
137
138
138 try {
139 try {
139 return action() ?? Promise.Reject(new Exception("The action returned null"));
140 return action() ?? Promise.Reject(new Exception("The action returned null"));
140 } catch (Exception err) {
141 } catch (Exception err) {
141 return Promise.Reject(err);
142 return Promise.Reject(err);
142 }
143 }
143 }
144 }
144
145
145 public static void NoWait(IPromise promise) {
146 public static void NoWait(IPromise promise) {
146 }
147 }
147
148
148 public static void NoWait(Task promise) {
149 public static void NoWait(Task promise) {
149 }
150 }
150
151
151 public static void NoWait<T>(Task<T> promise) {
152 public static void NoWait<T>(Task<T> promise) {
152 }
153 }
153
154
155 public static void Noop() {
156 }
157
158 public static void Noop(CancellationToken ct) {
159 ct.ThrowIfCancellationRequested();
160 }
161
162 public static Task CreateTask() {
163 return new Task(Noop);
164 }
165
166 public static Task CreateTask(CancellationToken ct) {
167 return new Task(Noop, ct);
168 }
169
154 [DebuggerStepThrough]
170 [DebuggerStepThrough]
155 public static IPromise<T> Run<T>(Func<IPromise<T>> action) {
171 public static IPromise<T> Run<T>(Func<IPromise<T>> action) {
156 ArgumentNotNull(action, "action");
172 ArgumentNotNull(action, "action");
157
173
158 try {
174 try {
159 return action() ?? Promise.Reject<T>(new Exception("The action returned null"));
175 return action() ?? Promise.Reject<T>(new Exception("The action returned null"));
160 } catch (Exception err) {
176 } catch (Exception err) {
161 return Promise.Reject<T>(err);
177 return Promise.Reject<T>(err);
162 }
178 }
163 }
179 }
164
180
165 #if NET_4_5
166 public static void NoWait(Task t) {
167 }
168 #endif
169
170 }
181 }
171 }
182 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now