# HG changeset patch # User cin # Date 2014-04-06 23:25:57 # Node ID 2fad2d1f4b03c217a54a1a5ca01c3317ad830680 # Parent 768f7deeb55bc33bd0bc5383560ecaafaf916084 small refactoring, cleanup. diff --git a/Implab.Fx/AnimationHelpers.cs b/Implab.Fx/AnimationHelpers.cs --- a/Implab.Fx/AnimationHelpers.cs +++ b/Implab.Fx/AnimationHelpers.cs @@ -38,14 +38,14 @@ namespace Implab.Fx return anim; } - public static Promise CloseFadeOut(this T ctl) where T : Form + public static IPromise CloseFadeOut(this T ctl) where T : Form { var anim = ctl.AnimateTransparency(0); return anim.Play().DispatchToControl(ctl).Then(frm => frm.Close()); } - public static Promise OverlayFadeIn(this Form that, T overlay) where T : Form + public static IPromise OverlayFadeIn(this Form that, T overlay) where T : Form { if (that == null) throw new ArgumentNullException("that"); diff --git a/Implab.Test/AsyncTests.cs b/Implab.Test/AsyncTests.cs --- a/Implab.Test/AsyncTests.cs +++ b/Implab.Test/AsyncTests.cs @@ -255,7 +255,7 @@ namespace Implab.Test { var t = Environment.TickCount; var res = args - .ChainedMap2( + .ChainedMap( x => pool.Invoke( () => Math.Sin(x * x) ), diff --git a/Implab/Parallels/ArrayTraits.cs b/Implab/Parallels/ArrayTraits.cs --- a/Implab/Parallels/ArrayTraits.cs +++ b/Implab/Parallels/ArrayTraits.cs @@ -105,7 +105,7 @@ namespace Implab.Parallels { } } - public static Promise ParallelMap (this TSrc[] source, Func transform, int threads) { + public static IPromise ParallelMap (this TSrc[] source, Func transform, int threads) { if (source == null) throw new ArgumentNullException("source"); if (transform == null) @@ -115,7 +115,7 @@ namespace Implab.Parallels { return mapper.Promise; } - public static Promise ParallelForEach(this TSrc[] source, Action action, int threads) { + public static IPromise ParallelForEach(this TSrc[] source, Action action, int threads) { if (source == null) throw new ArgumentNullException("source"); if (action == null) @@ -136,6 +136,7 @@ namespace Implab.Parallels { var promise = new Promise(); var res = new TDst[source.Length]; var pending = source.Length; + var semaphore = new Semaphore(threads, threads); AsyncPool.InvokeNewThread(() => { diff --git a/Implab/Parallels/DispatchPool.cs b/Implab/Parallels/DispatchPool.cs --- a/Implab/Parallels/DispatchPool.cs +++ b/Implab/Parallels/DispatchPool.cs @@ -143,18 +143,24 @@ namespace Implab.Parallels { // anyway it may take some time for the thread to start // we will ensure that at least one thread is running - if (AllocateThreadSlot(1)) { - // if there were no threads in the pool - var worker = new Thread(this.Worker); - worker.IsBackground = true; - worker.Start(); - } + EnsurePoolIsAlive(); } else { // if there is no sleeping threads in the pool - if (!StartWorker()) - // we haven't started a new thread, but the current can be on the way and it can't process the queue + if (!StartWorker()) { + // we haven't started a new thread, but the current can be on the way to terminate and it can't process the queue // send it a signal to spin again - SignalThread(); + SignalThread(); + EnsurePoolIsAlive(); + } + } + } + + private void EnsurePoolIsAlive() { + if (AllocateThreadSlot(1)) { + // if there were no threads in the pool + var worker = new Thread(this.Worker); + worker.IsBackground = true; + worker.Start(); } } @@ -177,12 +183,9 @@ namespace Implab.Parallels { // in case at the moment the last thread was being released // a new task was added to the queue, we need to try // to revoke the thread to avoid the situation when the task is left unprocessed - if (last && Sleep(0)) { // Sleep(0) will fetch pending task or will return false - if (AllocateThreadSlot(1)) - return true; // spin again... - else - SignalThread(); // since Sleep(0) has fetched the signal we neet to reschedule it - + if (last && FetchSignalOrWait(0)) { // FetchSignalOrWait(0) will fetch pending task or will return false + SignalThread(); // since FetchSignalOrWait(0) has fetched the signal we need to reschedule it + return AllocateThreadSlot(1); // ensure that at least one thread is alive } return false; diff --git a/Implab/Promise.cs b/Implab/Promise.cs --- a/Implab/Promise.cs +++ b/Implab/Promise.cs @@ -11,7 +11,7 @@ namespace Implab { public delegate T ErrorHandler(Exception e); public delegate void ResultHandler(T result); public delegate TNew ResultMapper(TSrc result); - public delegate Promise ChainedOperation(TSrc result); + public delegate IPromise ChainedOperation(TSrc result); /// /// Класс для асинхронного получения результатов. Так называемое "обещание". @@ -610,7 +610,7 @@ namespace Implab { /// Список обещаний. Если список пустой, то результирующее обещание возвращается уже выполненным. /// Обещание объединяющее в себе результат переданных обещаний. /// не может быть null - public static Promise CreateComposite(IList> promises) { + public static IPromise CreateComposite(IList> promises) { if (promises == null) throw new ArgumentNullException();