public override void performOperationStep(DeploymentOperation operationContext) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final org.camunda.bpm.container.impl.spi.PlatformServiceContainer serviceContainer = operationContext.getServiceContainer(); PlatformServiceContainer serviceContainer = operationContext.ServiceContainer; JobExecutorXml jobExecutorXml = getJobExecutorXml(operationContext); int queueSize = getQueueSize(jobExecutorXml); int corePoolSize = getCorePoolSize(jobExecutorXml); int maxPoolSize = getMaxPoolSize(jobExecutorXml); long keepAliveTime = getKeepAliveTime(jobExecutorXml); // initialize Queue & Executor services BlockingQueue <ThreadStart> threadPoolQueue = new ArrayBlockingQueue <ThreadStart>(queueSize); ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, threadPoolQueue); threadPoolExecutor.RejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy(); // construct the service for the thread pool JmxManagedThreadPool managedThreadPool = new JmxManagedThreadPool(threadPoolQueue, threadPoolExecutor); // install the service into the container serviceContainer.startService(ServiceTypes.BPM_PLATFORM, RuntimeContainerDelegateImpl.SERVICE_NAME_EXECUTOR, managedThreadPool); }
/// <summary> /// Set a gesture type queue. /// </summary> /// <param name="queuedSingleTaps">Gesture type queue.</param> public void SetQueuedSingleTaps(ArrayBlockingQueue queuedSingleTaps) { if (queuedSingleTaps == null) { Log.Info(TAG, "setSession error, arSession is null!"); return; } mQueuedSingleTaps = queuedSingleTaps; }
public RejectingJobExecutor() { BlockingQueue <ThreadStart> threadPoolQueue = new ArrayBlockingQueue <ThreadStart>(queueSize); threadPoolExecutor = new ThreadPoolExecutorAnonymousInnerClass(this, corePoolSize, maxPoolSize, TimeUnit.MILLISECONDS, threadPoolQueue); threadPoolExecutor.RejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy(); rejectedJobsHandler = new CallerRunsRejectedJobsHandler(); }
public _Thread_597(DomainSocket serv, byte[] clientMsg1, FileDescriptor[] passedFds , byte[] serverMsg1, ArrayBlockingQueue <System.Exception> threadResults) { this.serv = serv; this.clientMsg1 = clientMsg1; this.passedFds = passedFds; this.serverMsg1 = serverMsg1; this.threadResults = threadResults; }
protected internal override void startExecutingJobs() { if (threadPoolExecutor == null || threadPoolExecutor.Shutdown) { BlockingQueue <ThreadStart> threadPoolQueue = new ArrayBlockingQueue <ThreadStart>(queueSize); threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, 0L, TimeUnit.MILLISECONDS, threadPoolQueue); threadPoolExecutor.RejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy(); } base.startExecutingJobs(); }
public _Thread_463(DomainSocket[] preConnectedSockets, string TestPath, Type writeStrategyClass , byte[] clientMsg1, Type readStrategyClass, byte[] serverMsg1, byte clientMsg2, ArrayBlockingQueue <Exception> threadResults) { this.preConnectedSockets = preConnectedSockets; this.TestPath = TestPath; this.writeStrategyClass = writeStrategyClass; this.clientMsg1 = clientMsg1; this.readStrategyClass = readStrategyClass; this.serverMsg1 = serverMsg1; this.clientMsg2 = clientMsg2; this.threadResults = threadResults; }
public virtual BlockingQueue <IList <IMessage> > addQueue(string topic) { lock (this) { if (!queueMap.ContainsKey(topic)) { BlockingQueue <IList <IMessage> > q = new ArrayBlockingQueue <IList <IMessage> >(4096); queueMap[topic] = q; return(q); } throw new Exception("Topic " + topic + " already subscribed"); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test void shouldDoProcessingInitializationInOrder() throws Throwable //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: internal virtual void ShouldDoProcessingInitializationInOrder() { // GIVEN //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final org.neo4j.test.Race race = new org.neo4j.test.Race(); Race race = new Race(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final java.util.concurrent.atomic.AtomicInteger coordination = new java.util.concurrent.atomic.AtomicInteger(-1); AtomicInteger coordination = new AtomicInteger(-1); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final java.util.concurrent.atomic.AtomicInteger expected = new java.util.concurrent.atomic.AtomicInteger(); AtomicInteger expected = new AtomicInteger(); const int threads = 30; //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") final RecordCheckWorker<int>[] workers = new RecordCheckWorker[threads]; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': RecordCheckWorker <int>[] workers = new RecordCheckWorker[threads]; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final RecordProcessor<int> processor = new RecordProcessor_Adapter<int>() RecordProcessor <int> processor = new RecordProcessor_AdapterAnonymousInnerClass(this, expected); for (int id = 0; id < threads; id++) { ArrayBlockingQueue <int> queue = new ArrayBlockingQueue <int>(10); race.AddContestant(workers[id] = new RecordCheckWorker <int>(id, coordination, queue, processor)); } race.AddContestant(() => { try { long end = currentTimeMillis() + SECONDS.toMillis(100); while (currentTimeMillis() < end && expected.get() < threads) { parkNanos(MILLISECONDS.toNanos(10)); } assertEquals(threads, expected.get()); } finally { foreach (RecordCheckWorker <int> worker in workers) { worker.Done(); } } }); // WHEN race.Go(); }
/// <param name="maxCacheableBlockSize"> Max size of cached blocks including alignment padding, must be a power of 2 </param> /// <param name="maxCachedBlocks"> Max number of blocks of each size to store </param> public CachingOffHeapBlockAllocator(long maxCacheableBlockSize, int maxCachedBlocks) { requirePositive(maxCachedBlocks); this._maxCacheableBlockSize = requirePowerOfTwo(maxCacheableBlockSize); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int numOfCaches = log2floor(maxCacheableBlockSize) + 1; int numOfCaches = log2floor(maxCacheableBlockSize) + 1; //noinspection unchecked this._caches = new BlockingQueue[numOfCaches]; for (int i = 0; i < _caches.Length; i++) { _caches[i] = new ArrayBlockingQueue <OffHeapBlockAllocator_MemoryBlock>(maxCachedBlocks); } }
/// <summary>Test file descriptor passing.</summary> /// <exception cref="System.IO.IOException"/> /// <exception cref="System.Exception"/> public virtual void TestFdPassing() { string TestPath = new FilePath(sockDir.GetDir(), "test_sock").GetAbsolutePath(); byte[] clientMsg1 = new byte[] { unchecked ((int)(0x11)), unchecked ((int)(0x22)), unchecked ((int)(0x33)), unchecked ((int)(0x44)), unchecked ((int)(0x55)), unchecked ( (int)(0x66)) }; byte[] serverMsg1 = new byte[] { unchecked ((int)(0x31)), unchecked ((int)(0x30)), unchecked ((int)(0x32)), unchecked ((int)(0x34)), unchecked ((int)(0x31)), unchecked ( (int)(0x33)), unchecked ((int)(0x44)), unchecked ((int)(0x1)), unchecked ((int)(0x1 )), unchecked ((int)(0x1)), unchecked ((int)(0x1)), unchecked ((int)(0x1)) }; ArrayBlockingQueue <System.Exception> threadResults = new ArrayBlockingQueue <System.Exception >(2); DomainSocket serv = DomainSocket.BindAndListen(TestPath); TestDomainSocket.PassedFile[] passedFiles = new TestDomainSocket.PassedFile[] { new TestDomainSocket.PassedFile(1), new TestDomainSocket.PassedFile(2) }; FileDescriptor[] passedFds = new FileDescriptor[passedFiles.Length]; for (int i = 0; i < passedFiles.Length; i++) { passedFds[i] = passedFiles[i].GetInputStream().GetFD(); } Thread serverThread = new _Thread_597(serv, clientMsg1, passedFds, serverMsg1 , threadResults); // Run server serverThread.Start(); Thread clientThread = new _Thread_620(TestPath, clientMsg1, serverMsg1, passedFds , passedFiles, threadResults); clientThread.Start(); for (int i_1 = 0; i_1 < 2; i_1++) { System.Exception t = threadResults.Take(); if (!(t is TestDomainSocket.Success)) { NUnit.Framework.Assert.Fail(t.Message + ExceptionUtils.GetStackTrace(t)); } } serverThread.Join(120000); clientThread.Join(120000); serv.Close(); foreach (TestDomainSocket.PassedFile pf in passedFiles) { pf.Cleanup(); } }
private BlockingQueue <PullUpdateFuture> GetOrCreateQueue(Slave slave) { lock (this) { BlockingQueue <PullUpdateFuture> queue = _pullUpdateQueues[slave.ServerId]; if (queue == null) { // Create queue and worker queue = new ArrayBlockingQueue <PullUpdateFuture>(PULL_UPDATES_QUEUE_SIZE); _pullUpdateQueues[slave.ServerId] = queue; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final java.util.concurrent.BlockingQueue<PullUpdateFuture> finalQueue = queue; BlockingQueue <PullUpdateFuture> finalQueue = queue; _scheduler.schedule(Group.MASTER_TRANSACTION_PUSHING, new RunnableAnonymousInnerClass(this, finalQueue)); } return(queue); } }
/// <summary>Test a simple client/server interaction.</summary> /// <exception cref="System.IO.IOException"/> /// <exception cref="System.Exception"/> internal virtual void TestClientServer1(Type writeStrategyClass, Type readStrategyClass , DomainSocket[] preConnectedSockets) { string TestPath = new FilePath(sockDir.GetDir(), "test_sock_client_server1").GetAbsolutePath (); byte[] clientMsg1 = new byte[] { unchecked ((int)(0x1)), unchecked ((int)(0x2)), unchecked ( (int)(0x3)), unchecked ((int)(0x4)), unchecked ((int)(0x5)), unchecked ((int)(0x6)) }; byte[] serverMsg1 = new byte[] { unchecked ((int)(0x9)), unchecked ((int)(0x8)), unchecked ( (int)(0x7)), unchecked ((int)(0x6)), unchecked ((int)(0x5)) }; byte clientMsg2 = unchecked ((int)(0x45)); ArrayBlockingQueue <Exception> threadResults = new ArrayBlockingQueue <Exception>(2 ); DomainSocket serv = (preConnectedSockets != null) ? null : DomainSocket.BindAndListen (TestPath); Thread serverThread = new _Thread_435(preConnectedSockets, serv, clientMsg1 , readStrategyClass, writeStrategyClass, serverMsg1, clientMsg2, threadResults); // Run server serverThread.Start(); Thread clientThread = new _Thread_463(preConnectedSockets, TestPath, writeStrategyClass , clientMsg1, readStrategyClass, serverMsg1, clientMsg2, threadResults); clientThread.Start(); for (int i = 0; i < 2; i++) { Exception t = threadResults.Take(); if (!(t is TestDomainSocket.Success)) { NUnit.Framework.Assert.Fail(t.Message + ExceptionUtils.GetStackTrace(t)); } } serverThread.Join(120000); clientThread.Join(120000); if (serv != null) { serv.Close(); } }
public void QueueRetursWorkQueuContainsQueuedTasks() { IBlockingQueue <IRunnable> q = new ArrayBlockingQueue <IRunnable>(10); var es = new ThreadPoolExecutor(1, 1, Delays.Long, q); ExecutorService = es; FutureTask <bool>[] tasks = new FutureTask <bool> [_size]; for (int i = 0; i < _size; i++) { tasks[i] = new FutureTask <bool>(_mediumInterruptableAction, true); es.Execute(tasks[i]); } Thread.Sleep(Delays.Short); IBlockingQueue <IRunnable> wq = es.Queue; Assert.AreEqual(q, wq); Assert.IsFalse(wq.Contains(tasks[0])); Assert.IsTrue(wq.Contains(tasks[_size - 1])); for (int i = 1; i < _size; ++i) { tasks[i].Cancel(true); } }
public void RemoveRunnableRemovesQueuedTaskAndFailesToRemoveActiveTask() { IBlockingQueue <IRunnable> q = new ArrayBlockingQueue <IRunnable>(10); var es = new ThreadPoolExecutor(1, 1, Delays.Long, q); ExecutorService = es; FutureTask <bool>[] tasks = new FutureTask <bool> [5]; for (int i = 0; i < 5; i++) { tasks[i] = new FutureTask <bool>(_mediumInterruptableAction, true); es.Execute(tasks[i]); } Thread.Sleep(Delays.Short); Assert.IsFalse(es.Remove(tasks[0])); Assert.IsTrue(q.Contains(tasks[4])); Assert.IsTrue(q.Contains(tasks[3])); Assert.IsTrue(es.Remove(tasks[4])); Assert.IsFalse(es.Remove(tasks[4])); Assert.IsFalse(q.Contains(tasks[4])); Assert.IsTrue(q.Contains(tasks[3])); Assert.IsTrue(es.Remove(tasks[3])); Assert.IsFalse(q.Contains(tasks[3])); InterruptAndJoinPool(es); }
public void RemoveActionRemovesQueuedTaskAndFailesToRemoveActiveTask() { IBlockingQueue <IRunnable> q = new ArrayBlockingQueue <IRunnable>(10); var es = new ThreadPoolExecutor(1, 1, Delays.Long, q); ExecutorService = es; var tasks = new Action[5]; for (int i = 0; i < 5; i++) { int timeout = i; tasks[i] = NewInterruptableAction(Delays.Medium + TimeSpan.FromMilliseconds(timeout)); es.Execute(tasks[i]); } Thread.Sleep(Delays.Short); Assert.IsFalse(es.Remove(tasks[0])); Assert.That(q.Count, Is.EqualTo(4)); Assert.IsTrue(es.Remove(tasks[4])); Assert.IsFalse(es.Remove(tasks[4])); Assert.That(q.Count, Is.EqualTo(3)); Assert.IsTrue(es.Remove(tasks[3])); Assert.That(q.Count, Is.EqualTo(2)); InterruptAndJoinPool(es); }
public _Thread_620(string TestPath, byte[] clientMsg1, byte[] serverMsg1, FileDescriptor [] passedFds, TestDomainSocket.PassedFile[] passedFiles, ArrayBlockingQueue <System.Exception > threadResults) { this.TestPath = TestPath; this.clientMsg1 = clientMsg1; this.serverMsg1 = serverMsg1; this.passedFds = passedFds; this.passedFiles = passedFiles; this.threadResults = threadResults; }
internal long waitAvg; //average wait time public DressingRooms(int rooms) { buffer = new ArrayBlockingQueue <int>(rooms); } //end constructor
public void Command_RejectedExecutionSemaphoreWithFallback() { TestCircuitBreaker circuitBreaker = new TestCircuitBreaker(); ArrayBlockingQueue<bool> results = new ArrayBlockingQueue<bool>(2); AtomicBoolean exceptionReceived = new AtomicBoolean(); IRunnable r = new HystrixContextRunnable(new Runnable(() => { try { results.Add(new TestSemaphoreCommandWithFallback(circuitBreaker, 1, TimeSpan.FromMilliseconds(200), false).Execute()); } catch (Exception) { exceptionReceived.Value = true; } })); // 2 threads, the second should be rejected by the semaphore and return fallback Thread t1 = new Thread(r.Run); Thread t2 = new Thread(r.Run); t1.Start(); t2.Start(); try { t1.Join(); t2.Join(); } catch (Exception) { Assert.Fail("failed waiting on threads"); } if (exceptionReceived.Value) { Assert.Fail("We should have received a fallback response"); } // both threads should have returned values Assert.AreEqual(2, results.Count); // should contain both a true and false result Assert.IsTrue(results.Contains(true)); Assert.IsTrue(results.Contains(false)); Assert.AreEqual(1, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.Success)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.ExceptionThrown)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.Failure)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.FallbackFailure)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.FallbackRejection)); Assert.AreEqual(1, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.FallbackSuccess)); Assert.AreEqual(1, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.SemaphoreRejected)); // the rest should not be involved in this test Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.ShortCircuited)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.ThreadPoolRejected)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.Timeout)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.ResponseFromCache)); TestContext.WriteLine("**** DONE"); Assert.AreEqual(2, HystrixRequestLog.GetCurrentRequest().ExecutedCommands.Count()); Hystrix.Reset(); }
public void Command_ExecutionSemaphoreWithExecution() { TestCircuitBreaker circuitBreaker = new TestCircuitBreaker(); // single thread should work try { TestSemaphoreCommand command = new TestSemaphoreCommand(circuitBreaker, 1, TimeSpan.FromMilliseconds(200)); bool result = command.Execute(); Assert.IsFalse(command.IsExecutedInThread); Assert.IsTrue(result); } catch (Exception e) { // we shouldn't fail on this one throw new Exception("Unexpected exception.", e); } ArrayBlockingQueue<bool> results = new ArrayBlockingQueue<bool>(2); AtomicBoolean exceptionReceived = new AtomicBoolean(); TryableSemaphore semaphore = new TryableSemaphore(HystrixPropertyFactory.AsProperty(1)); IRunnable r = new HystrixContextRunnable(new Runnable(() => { try { results.Add(new TestSemaphoreCommand(circuitBreaker, semaphore, TimeSpan.FromMilliseconds(200)).Execute()); } catch (Exception) { exceptionReceived.Value = true; } })); // 2 threads, the second should be rejected by the semaphore Thread t1 = new Thread(r.Run); Thread t2 = new Thread(r.Run); t1.Start(); t2.Start(); try { t1.Join(); t2.Join(); } catch (Exception) { Assert.Fail("failed waiting on threads"); } if (!exceptionReceived.Value) { Assert.Fail("We expected an exception on the 2nd get"); } // only 1 value is expected as the other should have thrown an exception Assert.AreEqual(1, results.Count); // should contain only a true result Assert.IsTrue(results.Contains(true)); Assert.IsFalse(results.Contains(false)); Assert.AreEqual(2, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.Success)); Assert.AreEqual(1, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.ExceptionThrown)); // no failure ... we throw an exception because of rejection but the command does not fail execution Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.Failure)); // there is no fallback implemented so no failure can occur on it Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.FallbackFailure)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.FallbackRejection)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.FallbackSuccess)); // we rejected via semaphore Assert.AreEqual(1, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.SemaphoreRejected)); // the rest should not be involved in this test Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.ShortCircuited)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.ThreadPoolRejected)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.Timeout)); Assert.AreEqual(0, circuitBreaker.Metrics.GetRollingCount(HystrixRollingNumberEvent.ResponseFromCache)); Assert.AreEqual(3, HystrixRequestLog.GetCurrentRequest().ExecutedCommands.Count()); Hystrix.Reset(); }
//JAVA TO C# CONVERTER WARNING: 'final' parameters are ignored unless the option to convert to C# 7.2 'in' parameters is selected: //ORIGINAL LINE: public static <RECORD> void distributeRecords(int numberOfThreads, String workerNames, int queueSize, java.util.Iterator<RECORD> records, final org.neo4j.helpers.progress.ProgressListener progress, RecordProcessor<RECORD> processor, org.neo4j.consistency.checking.full.QueueDistribution_QueueDistributor<RECORD> idDistributor) public static void DistributeRecords <RECORD>(int numberOfThreads, string workerNames, int queueSize, IEnumerator <RECORD> records, ProgressListener progress, RecordProcessor <RECORD> processor, QueueDistribution_QueueDistributor <RECORD> idDistributor) { //JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops: if (!records.hasNext()) { return; } //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") final java.util.concurrent.ArrayBlockingQueue<RECORD>[] recordQ = new java.util.concurrent.ArrayBlockingQueue[numberOfThreads]; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': ArrayBlockingQueue <RECORD>[] recordQ = new ArrayBlockingQueue[numberOfThreads]; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final org.neo4j.unsafe.impl.batchimport.cache.idmapping.string.Workers<RecordCheckWorker<RECORD>> workers = new org.neo4j.unsafe.impl.batchimport.cache.idmapping.string.Workers<>(workerNames); Workers <RecordCheckWorker <RECORD> > workers = new Workers <RecordCheckWorker <RECORD> >(workerNames); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final java.util.concurrent.atomic.AtomicInteger idGroup = new java.util.concurrent.atomic.AtomicInteger(-1); AtomicInteger idGroup = new AtomicInteger(-1); for (int threadId = 0; threadId < numberOfThreads; threadId++) { recordQ[threadId] = new ArrayBlockingQueue <RECORD>(queueSize); workers.Start(new RecordCheckWorker <RECORD>(threadId, idGroup, recordQ[threadId], processor)); } //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int[] recsProcessed = new int[numberOfThreads]; int[] recsProcessed = new int[numberOfThreads]; RecordConsumer <RECORD> recordConsumer = (record, qIndex) => { recordQ[qIndex].put(record); recsProcessed[qIndex]++; }; try { while (records.MoveNext()) { try { // Put records into the queues using the queue distributor. Each Worker will pull and process. RECORD record = records.Current; idDistributor.Distribute(record, recordConsumer); progress.Add(1); } catch (InterruptedException) { Thread.CurrentThread.Interrupt(); break; } } // No more records to distribute, mark as done so that the workers will exit when no more records in queue. foreach (RecordCheckWorker <RECORD> worker in workers) { worker.Done(); } workers.AwaitAndThrowOnError(); } catch (InterruptedException) { Thread.CurrentThread.Interrupt(); throw new Exception("Was interrupted while awaiting completion"); } }