##// END OF EJS Templates
inital progress handling
cin -
r7:7ea9363fef6c promises
parent child
Show More
@@ -0,0 +1,33
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Implab
7 {
8 public interface IPromise
9 {
10 /// <summary>
11 /// Check whereather the promise has no more than one dependent promise.
12 /// </summary>
13 bool IsExclusive
14 {
15 get;
16 }
17
18 /// <summary>
19 /// The current state of the promise.
20 /// </summary>
21 PromiseState State
22 {
23 get;
24 }
25
26 /// <summary>
27 /// Tries to cancel the promise or the complete chain.
28 /// </summary>
29 /// <param name="dependencies">Try to cancel the parent promise is it has the only one child</param>
30 /// <returns></returns>
31 bool Cancel(bool dependencies);
32 }
33 }
@@ -0,0 +1,36
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Implab
7 {
8
9 public class ProgressInitEventArgs: EventArgs
10 {
11 public float MaxProgress
12 {
13 get;
14 private set;
15 }
16
17 public float CurrentProgress
18 {
19 get;
20 private set;
21 }
22
23 public string Message
24 {
25 get;
26 private set;
27 }
28
29 public ProgressInitEventArgs(float current, float max, string message)
30 {
31 this.MaxProgress = max;
32 this.CurrentProgress = current;
33 this.Message = message;
34 }
35 }
36 }
@@ -0,0 +1,15
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Implab
7 {
8 public enum PromiseState
9 {
10 Unresolved,
11 Resolved,
12 Cancelled,
13 Rejected
14 }
15 }
@@ -0,0 +1,113
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
6
7 namespace Implab
8 {
9 /// <summary>
10 /// This class allows to interact with asyncronuos task.
11 /// </summary>
12 /// <remarks>
13 /// Members of this object are thread safe.
14 /// </remarks>
15 class TaskController
16 {
17 object m_lock;
18 string m_message;
19 bool m_cancelled;
20
21 float m_current;
22 float m_max;
23
24 public event EventHandler<ValueEventArgs<string>> MessageUpdated;
25 public event EventHandler<ValueEventArgs<float>> ProgressUpdated;
26 public event EventHandler<ProgressInitEventArgs> ProgressInit;
27
28 public TaskController()
29 {
30 m_lock = new Object();
31 }
32
33 public string Message
34 {
35 get
36 {
37 lock (m_lock)
38 return m_message;
39 }
40 set
41 {
42 lock (m_lock)
43 {
44 m_message = value;
45 OnMessageUpdated();
46 }
47 }
48 }
49
50 public float CurrentProgress
51 {
52 get
53 {
54 lock (m_lock)
55 return m_current;
56 }
57 set
58 {
59 lock (m_lock)
60 {
61 var prev = m_current;
62 m_current = value;
63 if (m_current >= m_max)
64 m_current = m_max;
65 if (m_current != prev)
66 OnProgressUpdated();
67 }
68 }
69 }
70
71 public void InitProgress(float current, float max, string message)
72 {
73 if (max < 0)
74 throw new ArgumentOutOfRangeException("max");
75 if (current < 0 || current > max)
76 throw new ArgumentOutOfRangeException("current");
77
78 lock(m_lock) {
79 m_current = current;
80 m_max = max;
81 m_message = message;
82 OnProgressInit();
83 }
84 }
85
86 protected virtual void OnMessageUpdated()
87 {
88 var temp = MessageUpdated;
89 if (temp != null)
90 {
91 temp(this, new ValueEventArgs<string>(m_message));
92 }
93 }
94
95 protected virtual void OnProgressUpdated()
96 {
97 var temp = ProgressUpdated;
98 if (temp != null)
99 {
100 temp(this,new ValueEventArgs<float>(m_current));
101 }
102 }
103
104 protected virtual void OnProgressInit()
105 {
106 var temp = ProgressInit;
107 if (temp != null)
108 {
109 temp(this, new ProgressInitEventArgs(m_current,m_max, m_message));
110 }
111 }
112 }
113 }
@@ -0,0 +1,20
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Implab
7 {
8 public class ValueEventArgs<T>: EventArgs
9 {
10 public ValueEventArgs(T value)
11 {
12 this.Value = value;
13 }
14 public T Value
15 {
16 get;
17 private set;
18 }
19 }
20 }
1 NO CONTENT: modified file, binary diff hidden
@@ -32,10 +32,14
32 32 <Reference Include="System" />
33 33 </ItemGroup>
34 34 <ItemGroup>
35 <Compile Include="ICancellable.cs" />
36 <Compile Include="TaskController.cs" />
37 <Compile Include="ProgressInitEventArgs.cs" />
35 38 <Compile Include="Properties\AssemblyInfo.cs" />
36 39 <Compile Include="Promise.cs" />
37 40 <Compile Include="AsyncPool.cs" />
38 41 <Compile Include="Safe.cs" />
42 <Compile Include="ValueEventArgs.cs" />
39 43 </ItemGroup>
40 44 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
41 45 <ItemGroup>
@@ -48,30 +48,32 namespace Implab {
48 48 /// только инициатор обещания иначе могут возникнуть противоречия.
49 49 /// </para>
50 50 /// </remarks>
51 public class Promise<T> {
51 public class Promise<T>: IPromise {
52 52
53 53 struct ResultHandlerInfo {
54 54 public ResultHandler<T> resultHandler;
55 55 public ErrorHandler errorHandler;
56 }
57
58 enum State {
59 Unresolved,
60 Resolving,
61 Resolved,
62 Cancelled
56 public Action cancelHandler;
63 57 }
64 58
65 59 LinkedList<ResultHandlerInfo> m_handlersChain = new LinkedList<ResultHandlerInfo>();
66 State m_state;
60 PromiseState m_state;
67 61 bool m_cancellable;
68 62 T m_result;
69 63 Exception m_error;
64 IPromise m_parent;
65 int m_childrenCount;
70 66
71 67 public Promise() {
72 68 m_cancellable = true;
73 69 }
74 70
71 public Promise(IPromise parent, bool cancellable)
72 {
73 m_cancellable = cancellable;
74 m_parent = parent;
75 }
76
75 77 /// <summary>
76 78 /// Событие, возникающее при отмене асинхронной операции.
77 79 /// </summary>
@@ -87,12 +89,12 namespace Implab {
87 89 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
88 90 public void Resolve(T result) {
89 91 lock (this) {
90 if (m_state == State.Cancelled)
92 if (m_state == PromiseState.Cancelled)
91 93 return;
92 if (m_state != State.Unresolved)
94 if (m_state != PromiseState.Unresolved)
93 95 throw new InvalidOperationException("The promise is already resolved");
94 96 m_result = result;
95 m_state = State.Resolving;
97 m_state = PromiseState.Resolved;
96 98 }
97 99
98 100 ResultHandlerInfo handler;
@@ -107,12 +109,12 namespace Implab {
107 109 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
108 110 public void Reject(Exception error) {
109 111 lock (this) {
110 if (m_state == State.Cancelled)
112 if (m_state == PromiseState.Cancelled)
111 113 return;
112 if (m_state != State.Unresolved)
114 if (m_state != PromiseState.Unresolved)
113 115 throw new InvalidOperationException("The promise is already resolved");
114 116 m_error = error;
115 m_state = State.Resolving;
117 m_state = PromiseState.Rejected;
116 118 }
117 119
118 120 ResultHandlerInfo handler;
@@ -126,8 +128,9 namespace Implab {
126 128 /// <returns><c>true</c> Операция была отменена, обработчики не будут вызваны.<c>false</c> отмена не возможна, поскольку обещание уже выполнено и обработчики отработали.</returns>
127 129 public bool Cancel() {
128 130 lock (this) {
129 if (m_state == State.Unresolved && m_cancellable) {
130 m_state = State.Cancelled;
131 if (m_state == PromiseState.Unresolved && m_cancellable)
132 {
133 m_state = PromiseState.Cancelled;
131 134 EventHandler temp = Cancelled;
132 135
133 136 if (temp != null)
@@ -348,14 +351,13 namespace Implab {
348 351 handler = default(ResultHandlerInfo);
349 352
350 353 lock (this) {
351 Debug.Assert(m_state == State.Resolving);
354 Debug.Assert(m_state != PromiseState.Unresolved);
352 355
353 356 if (m_handlersChain.Count > 0) {
354 357 handler = m_handlersChain.First.Value;
355 358 m_handlersChain.RemoveFirst();
356 359 return true;
357 360 } else {
358 m_state = State.Resolved;
359 361 return false;
360 362 }
361 363 }
@@ -365,7 +367,7 namespace Implab {
365 367 bool invokeRequired = false;
366 368
367 369 lock (this) {
368 if (m_state != State.Resolved)
370 if (m_state == PromiseState.Unresolved)
369 371 m_handlersChain.AddLast(handler);
370 372 else
371 373 invokeRequired = true;
General Comments 0
You need to be logged in to leave comments. Login now