public void InvokeInParallel(IServiceContext serviceContext, bool inheritThreadLocals, params Runnable[] runnables) { CountDownLatch latch = new CountDownLatch(runnables.Length); ParamHolder <Exception> throwableHolder = new ParamHolder <Exception>(); IForkState forkState = inheritThreadLocals ? ThreadLocalCleanupController.CreateForkState() : null; Thread[] threads = new Thread[runnables.Length]; for (int a = runnables.Length; a-- > 0;) { Runnable catchingRunnable = new CatchingRunnable(forkState, runnables[a], latch, throwableHolder, ThreadLocalCleanupController); Thread thread = new Thread(delegate() { catchingRunnable.Run(); }); thread.IsBackground = true; threads[a] = thread; } foreach (Thread thread in threads) { thread.Start(); } latch.Await(TimeSpan.FromMilliseconds(Timeout)); if (throwableHolder.Value != null) { throw RuntimeExceptionUtil.Mask(throwableHolder.Value, "Error occured while invoking runnables"); } }
public AbstractRunnableHandle(IList <V> items, IThreadLocalCleanupController threadLocalCleanupController) { this.latch = new CountDownLatch(items.Count); this.exHolder = new InterruptingParamHolder(Thread.CurrentThread); this.items = items; this.threadLocalCleanupController = threadLocalCleanupController; this.forkState = threadLocalCleanupController.CreateForkState(); }
public void Run() { try { Thread currentThread = Thread.CurrentThread; String oldName = currentThread.Name; if (buildThreadLocals) { String name = runnableHandle.createdThread.Name; currentThread.Name = name + " " + oldName; } try { Object parallelLock = runnableHandle.parallelLock; IList <V> items = runnableHandle.items; IForkState forkState = runnableHandle.forkState; ParamHolder <Exception> exHolder = runnableHandle.exHolder; CountDownLatch latch = runnableHandle.latch; while (true) { V item; lock (parallelLock) { if (exHolder.Value != null) { // an uncatched error occurred somewhere return; } // pop the last item of the queue item = items[items.Count - 1]; items.RemoveAt(items.Count - 1); } if (item == null) { // queue finished return; } try { if (buildThreadLocals) { forkState.Use(runnableHandle.run, item); } else { runnableHandle.run(item); } } catch (Exception e) { lock (parallelLock) { if (exHolder.Value == null) { exHolder.Value = e; } } } finally { latch.CountDown(); } } } finally { if (buildThreadLocals) { currentThread.Name = oldName; } } } finally { if (buildThreadLocals) { runnableHandle.threadLocalCleanupController.CleanupThreadLocal(); } } }