@@ -38,14 +38,14 namespace Implab.Fx | |||||
38 | return anim; |
|
38 | return anim; | |
39 | } |
|
39 | } | |
40 |
|
40 | |||
41 | public static Promise<T> CloseFadeOut<T>(this T ctl) where T : Form |
|
41 | public static IPromise<T> CloseFadeOut<T>(this T ctl) where T : Form | |
42 | { |
|
42 | { | |
43 | var anim = ctl.AnimateTransparency(0); |
|
43 | var anim = ctl.AnimateTransparency(0); | |
44 |
|
44 | |||
45 | return anim.Play().DispatchToControl(ctl).Then(frm => frm.Close()); |
|
45 | return anim.Play().DispatchToControl(ctl).Then(frm => frm.Close()); | |
46 | } |
|
46 | } | |
47 |
|
47 | |||
48 | public static Promise<T> OverlayFadeIn<T>(this Form that, T overlay) where T : Form |
|
48 | public static IPromise<T> OverlayFadeIn<T>(this Form that, T overlay) where T : Form | |
49 | { |
|
49 | { | |
50 | if (that == null) |
|
50 | if (that == null) | |
51 | throw new ArgumentNullException("that"); |
|
51 | throw new ArgumentNullException("that"); |
@@ -255,7 +255,7 namespace Implab.Test { | |||||
255 |
|
255 | |||
256 | var t = Environment.TickCount; |
|
256 | var t = Environment.TickCount; | |
257 | var res = args |
|
257 | var res = args | |
258 |
.ChainedMap |
|
258 | .ChainedMap( | |
259 | x => pool.Invoke( |
|
259 | x => pool.Invoke( | |
260 | () => Math.Sin(x * x) |
|
260 | () => Math.Sin(x * x) | |
261 | ), |
|
261 | ), |
@@ -105,7 +105,7 namespace Implab.Parallels { | |||||
105 | } |
|
105 | } | |
106 | } |
|
106 | } | |
107 |
|
107 | |||
108 | public static Promise<TDst[]> ParallelMap<TSrc, TDst> (this TSrc[] source, Func<TSrc,TDst> transform, int threads) { |
|
108 | public static IPromise<TDst[]> ParallelMap<TSrc, TDst> (this TSrc[] source, Func<TSrc,TDst> transform, int threads) { | |
109 | if (source == null) |
|
109 | if (source == null) | |
110 | throw new ArgumentNullException("source"); |
|
110 | throw new ArgumentNullException("source"); | |
111 | if (transform == null) |
|
111 | if (transform == null) | |
@@ -115,7 +115,7 namespace Implab.Parallels { | |||||
115 | return mapper.Promise; |
|
115 | return mapper.Promise; | |
116 | } |
|
116 | } | |
117 |
|
117 | |||
118 | public static Promise<int> ParallelForEach<TSrc>(this TSrc[] source, Action<TSrc> action, int threads) { |
|
118 | public static IPromise<int> ParallelForEach<TSrc>(this TSrc[] source, Action<TSrc> action, int threads) { | |
119 | if (source == null) |
|
119 | if (source == null) | |
120 | throw new ArgumentNullException("source"); |
|
120 | throw new ArgumentNullException("source"); | |
121 | if (action == null) |
|
121 | if (action == null) | |
@@ -136,6 +136,7 namespace Implab.Parallels { | |||||
136 | var promise = new Promise<TDst[]>(); |
|
136 | var promise = new Promise<TDst[]>(); | |
137 | var res = new TDst[source.Length]; |
|
137 | var res = new TDst[source.Length]; | |
138 | var pending = source.Length; |
|
138 | var pending = source.Length; | |
|
139 | ||||
139 | var semaphore = new Semaphore(threads, threads); |
|
140 | var semaphore = new Semaphore(threads, threads); | |
140 |
|
141 | |||
141 | AsyncPool.InvokeNewThread(() => { |
|
142 | AsyncPool.InvokeNewThread(() => { |
@@ -143,19 +143,25 namespace Implab.Parallels { | |||||
143 | // anyway it may take some time for the thread to start |
|
143 | // anyway it may take some time for the thread to start | |
144 | // we will ensure that at least one thread is running |
|
144 | // we will ensure that at least one thread is running | |
145 |
|
145 | |||
|
146 | EnsurePoolIsAlive(); | |||
|
147 | } else { | |||
|
148 | // if there is no sleeping threads in the pool | |||
|
149 | if (!StartWorker()) { | |||
|
150 | // we haven't started a new thread, but the current can be on the way to terminate and it can't process the queue | |||
|
151 | // send it a signal to spin again | |||
|
152 | SignalThread(); | |||
|
153 | EnsurePoolIsAlive(); | |||
|
154 | } | |||
|
155 | } | |||
|
156 | } | |||
|
157 | ||||
|
158 | private void EnsurePoolIsAlive() { | |||
146 |
|
|
159 | if (AllocateThreadSlot(1)) { | |
147 |
|
|
160 | // if there were no threads in the pool | |
148 |
|
|
161 | var worker = new Thread(this.Worker); | |
149 |
|
|
162 | worker.IsBackground = true; | |
150 |
|
|
163 | worker.Start(); | |
151 |
|
|
164 | } | |
152 | } else { |
|
|||
153 | // if there is no sleeping threads in the pool |
|
|||
154 | if (!StartWorker()) |
|
|||
155 | // we haven't started a new thread, but the current can be on the way and it can't process the queue |
|
|||
156 | // send it a signal to spin again |
|
|||
157 | SignalThread(); |
|
|||
158 | } |
|
|||
159 | } |
|
165 | } | |
160 |
|
166 | |||
161 | private bool Suspend() { |
|
167 | private bool Suspend() { | |
@@ -177,12 +183,9 namespace Implab.Parallels { | |||||
177 | // in case at the moment the last thread was being released |
|
183 | // in case at the moment the last thread was being released | |
178 | // a new task was added to the queue, we need to try |
|
184 | // a new task was added to the queue, we need to try | |
179 | // to revoke the thread to avoid the situation when the task is left unprocessed |
|
185 | // to revoke the thread to avoid the situation when the task is left unprocessed | |
180 |
if (last && |
|
186 | if (last && FetchSignalOrWait(0)) { // FetchSignalOrWait(0) will fetch pending task or will return false | |
181 | if (AllocateThreadSlot(1)) |
|
187 | SignalThread(); // since FetchSignalOrWait(0) has fetched the signal we need to reschedule it | |
182 | return true; // spin again... |
|
188 | return AllocateThreadSlot(1); // ensure that at least one thread is alive | |
183 | else |
|
|||
184 | SignalThread(); // since Sleep(0) has fetched the signal we neet to reschedule it |
|
|||
185 |
|
||||
186 | } |
|
189 | } | |
187 |
|
190 | |||
188 | return false; |
|
191 | return false; |
@@ -11,7 +11,7 namespace Implab { | |||||
11 | public delegate T ErrorHandler<out T>(Exception e); |
|
11 | public delegate T ErrorHandler<out T>(Exception e); | |
12 | public delegate void ResultHandler<in T>(T result); |
|
12 | public delegate void ResultHandler<in T>(T result); | |
13 | public delegate TNew ResultMapper<in TSrc, out TNew>(TSrc result); |
|
13 | public delegate TNew ResultMapper<in TSrc, out TNew>(TSrc result); | |
14 | public delegate Promise<TNew> ChainedOperation<in TSrc,TNew>(TSrc result); |
|
14 | public delegate IPromise<TNew> ChainedOperation<in TSrc,TNew>(TSrc result); | |
15 |
|
15 | |||
16 | /// <summary> |
|
16 | /// <summary> | |
17 | /// Класс для асинхронного получения результатов. Так называемое "обещание". |
|
17 | /// Класс для асинхронного получения результатов. Так называемое "обещание". | |
@@ -610,7 +610,7 namespace Implab { | |||||
610 | /// <param name="promises">Список обещаний. Если список пустой, то результирующее обещание возвращается уже выполненным.</param> |
|
610 | /// <param name="promises">Список обещаний. Если список пустой, то результирующее обещание возвращается уже выполненным.</param> | |
611 | /// <returns>Обещание объединяющее в себе результат переданных обещаний.</returns> |
|
611 | /// <returns>Обещание объединяющее в себе результат переданных обещаний.</returns> | |
612 | /// <exception cref="ArgumentNullException"><paramref name="promises"/> не может быть null</exception> |
|
612 | /// <exception cref="ArgumentNullException"><paramref name="promises"/> не может быть null</exception> | |
613 | public static Promise<T[]> CreateComposite(IList<Promise<T>> promises) { |
|
613 | public static IPromise<T[]> CreateComposite(IList<IPromise<T>> promises) { | |
614 | if (promises == null) |
|
614 | if (promises == null) | |
615 | throw new ArgumentNullException(); |
|
615 | throw new ArgumentNullException(); | |
616 |
|
616 |
General Comments 0
You need to be logged in to leave comments.
Login now