@@ -38,14 +38,14 namespace Implab.Fx | |||
|
38 | 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 | 43 | var anim = ctl.AnimateTransparency(0); |
|
44 | 44 | |
|
45 | 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 | 50 | if (that == null) |
|
51 | 51 | throw new ArgumentNullException("that"); |
@@ -255,7 +255,7 namespace Implab.Test { | |||
|
255 | 255 | |
|
256 | 256 | var t = Environment.TickCount; |
|
257 | 257 | var res = args |
|
258 |
.ChainedMap |
|
|
258 | .ChainedMap( | |
|
259 | 259 | x => pool.Invoke( |
|
260 | 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 | 109 | if (source == null) |
|
110 | 110 | throw new ArgumentNullException("source"); |
|
111 | 111 | if (transform == null) |
@@ -115,7 +115,7 namespace Implab.Parallels { | |||
|
115 | 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 | 119 | if (source == null) |
|
120 | 120 | throw new ArgumentNullException("source"); |
|
121 | 121 | if (action == null) |
@@ -136,6 +136,7 namespace Implab.Parallels { | |||
|
136 | 136 | var promise = new Promise<TDst[]>(); |
|
137 | 137 | var res = new TDst[source.Length]; |
|
138 | 138 | var pending = source.Length; |
|
139 | ||
|
139 | 140 | var semaphore = new Semaphore(threads, threads); |
|
140 | 141 | |
|
141 | 142 | AsyncPool.InvokeNewThread(() => { |
@@ -143,18 +143,24 namespace Implab.Parallels { | |||
|
143 | 143 | // anyway it may take some time for the thread to start |
|
144 | 144 | // we will ensure that at least one thread is running |
|
145 | 145 | |
|
146 | if (AllocateThreadSlot(1)) { | |
|
147 | // if there were no threads in the pool | |
|
148 | var worker = new Thread(this.Worker); | |
|
149 | worker.IsBackground = true; | |
|
150 | worker.Start(); | |
|
151 | } | |
|
146 | EnsurePoolIsAlive(); | |
|
152 | 147 | } else { |
|
153 | 148 | // 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 | |
|
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 | |
|
156 | 151 | // send it a signal to spin again |
|
157 |
SignalThread(); |
|
|
152 | SignalThread(); | |
|
153 | EnsurePoolIsAlive(); | |
|
154 | } | |
|
155 | } | |
|
156 | } | |
|
157 | ||
|
158 | private void EnsurePoolIsAlive() { | |
|
159 | if (AllocateThreadSlot(1)) { | |
|
160 | // if there were no threads in the pool | |
|
161 | var worker = new Thread(this.Worker); | |
|
162 | worker.IsBackground = true; | |
|
163 | worker.Start(); | |
|
158 | 164 | } |
|
159 | 165 | } |
|
160 | 166 | |
@@ -177,12 +183,9 namespace Implab.Parallels { | |||
|
177 | 183 | // in case at the moment the last thread was being released |
|
178 | 184 | // a new task was added to the queue, we need to try |
|
179 | 185 | // to revoke the thread to avoid the situation when the task is left unprocessed |
|
180 |
if (last && |
|
|
181 | if (AllocateThreadSlot(1)) | |
|
182 | return true; // spin again... | |
|
183 | else | |
|
184 | SignalThread(); // since Sleep(0) has fetched the signal we neet to reschedule it | |
|
185 | ||
|
186 | if (last && FetchSignalOrWait(0)) { // FetchSignalOrWait(0) will fetch pending task or will return false | |
|
187 | SignalThread(); // since FetchSignalOrWait(0) has fetched the signal we need to reschedule it | |
|
188 | return AllocateThreadSlot(1); // ensure that at least one thread is alive | |
|
186 | 189 | } |
|
187 | 190 | |
|
188 | 191 | return false; |
@@ -11,7 +11,7 namespace Implab { | |||
|
11 | 11 | public delegate T ErrorHandler<out T>(Exception e); |
|
12 | 12 | public delegate void ResultHandler<in T>(T result); |
|
13 | 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 | 16 | /// <summary> |
|
17 | 17 | /// Класс для асинхронного получения результатов. Так называемое "обещание". |
@@ -610,7 +610,7 namespace Implab { | |||
|
610 | 610 | /// <param name="promises">Список обещаний. Если список пустой, то результирующее обещание возвращается уже выполненным.</param> |
|
611 | 611 | /// <returns>Обещание объединяющее в себе результат переданных обещаний.</returns> |
|
612 | 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 | 614 | if (promises == null) |
|
615 | 615 | throw new ArgumentNullException(); |
|
616 | 616 |
General Comments 0
You need to be logged in to leave comments.
Login now