public void ExecuteJobs() { while (!QueueManager.IsCompleted()) // as long as getting work items { WorkerJob workerJob = QueueManager.GetJobItem(); if (workerJob != null) { //Stopwatch stopwatch = Stopwatch.StartNew(); //var maxHandleTimes = this.workers.Select(i => i.Value.MaxHandleTime); //stopwatch.Stop(); //Console.WriteLine($"---------------------------- action taken: {stopwatch.Elapsed} ------------------------"); var duration = workerJob.Duration.TotalMilliseconds; var closestWorkerIds = workersMaxHandleTime .Where(kvp => kvp.Value >= duration) .Select(kvp => (kvp, distance: kvp.Value - duration)) .OrderBy(o => o.distance); if (closestWorkerIds.Count() > 0) { var workerId = closestWorkerIds.First().kvp.Key; _ = Task.Run(() => workers[workerId].DoWork(workerJob.Method, workerJob.Duration)); } else { Console.WriteLine($"Did not find suitable worker for {workerJob} job."); } } } }
public static void AddWorkItem(WorkerJob workerItem) { bool success; do { success = (workerItem.HighPriority) ? highPriorityQueue.TryAdd(workerItem) : lowPriorityQueue.TryAdd(workerItem); } while (!success); }
public static WorkerJob GetJobItem() { WorkerJob workerItem = null; bool success; do { if (highPriorityQueue.Count == 0 && lowPriorityQueue.Count == 0) { break; // in case of empty queues } success = (highPriorityQueue.Count > 0) ? // <-- always prefer the high priority job queue highPriorityQueue.TryTake(out workerItem) : lowPriorityQueue.TryTake(out workerItem); } while (!success); return(workerItem); }
const int NUM_OF_WORKERS = 1000; // predefine the number of resource workers // API EndPoint public static void AddNewJob(int id, Action method, TimeSpan duration, bool highPriority) { var job = new WorkerJob(id, method, duration, highPriority); Task AddNewJobTask = Task.Run(() => QueueManager.AddWorkItem(job)); }