public void EnqueueTask(ThreadWrapperBase task)
 {
     lock (workersQueued)
     {
         workersQueued.Add(task);
     }
 }
Example #2
0
		public void EnqueueTask(ThreadWrapperBase task)
		{
			lock (workersQueued)
			{
				workersQueued.Add(task);
			}
		}
        private void AllocateWork()
        {
            while (true)
            {
                // Remove completed tasks.
                // Because we are not using foreach, the collection
                // doesn't need to be locked. It could grow while this
                // method is working, but that would only result in a
                // slot being missed until the next pass, which is acceptable.
                // It can't shrink, because no other methods remove work.
                // We count in reverse order so a single pass can
                // remove multiple entries without rearranging the items
                // that haven't been scanned.
                // Deferring the locking improves performance.
                for (int i = workers.Count - 1; i >= 0; i--)
                {
                    if (workers[i].Status == StatusState.Completed)
                    {
                        ThreadWrapperBase worker = workers[i];
                        lock (workersCompleted)
                        {
                            workersCompleted.Add(worker);
                        }
                        lock (workers)
                        {
                            workers.Remove(worker);
                        }
                        // Fire notification event.
                        invokeContext.Invoke(new WorkerCompletedEventHandler(OnWorkerCompleted),
                                             new object[] { this, new WorkerCompletedEventArgs((EratosthenesTask)worker) });
                    }
                }

                // Allocate new work while threads are available.
                while (workersQueued.Count > 0 &&
                       workers.Count < maxThreads)
                {
                    ThreadWrapperBase task = workersQueued[0];

                    // Some exception handling code here would be useful
                    // to prevent performing one part of this sequence
                    // (starting the task), without the other (removing it
                    // from the queue).
                    lock (workers)
                    {
                        workers.Add(task);
                    }
                    lock (workersQueued)
                    {
                        workersQueued.RemoveAt(0);
                    }
                    task.Start();
                }

                // Report progress.
                for (int i = workers.Count - 1; i >= 0; i--)
                {
                    ThreadWrapperBase worker = workers[i];
                    if (worker.Status == StatusState.InProgress)
                    {
                        // Fire notification event.
                        if (invokeContext.Created)
                        {
                            invokeContext.Invoke(new ReportWorkerProgressEventHandler(OnReportWorkerProgress),
                                                 new object[] { this,
                                                                new ReportWorkerProgressEventArgs(worker.ID, worker.Progress) });
                        }
                    }
                }

                // Pause 2 seconds before the next pass.
                // You could make this variable configurable.
                Thread.Sleep(TimeSpan.FromSeconds(2));
            }
        }