public JobWorker(int concurrentSize) { using (JobsRepo repo = new JobsRepo()) { while (true) { JobInfo job = Queue.pop(); long delay = (job.RunAt.Ticks / TimeSpan.TicksPerMillisecond) - (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond); //Console.WriteLine("[" + job.Id + "] job.RunAt=> " + job.RunAt + ", DateTime.Now=>" + DateTime.Now + ", delay =>" + delay); if (delay > 0) { Task.Delay(TimeSpan.FromMilliseconds(delay)).Wait(); } if (repo.GetJob(job.Id).State == 0) { if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("[" + job.Id + "]" + "O"); } else { Console.Write("[" + job.Id + "]" + "X"); } } } } }
private void DoWorkerThread() { using (var repo = new JobsRepo()) { while (true) { while (_workItems.Count > 0) { JobInfo job = null; lock (_workItems) { if (_workItems.Count > 0) { job = _workItems.Dequeue(); } } if (job == null) { continue; } if (repo.GetJob(job.Id).State == 0) { if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.WriteLine($"[Consumer][Done] #{job.Id}"); } else { Console.WriteLine($"[Consumer][Failed] #{job.Id}"); } } if (_cancelFlag) { break; } } if (_stopFlag || _cancelFlag) { break; } if (_enqueueNotify.WaitOne(_maxWorkerThreadTimeout, true)) { continue; } break; } } _workerThreads.Remove(Thread.CurrentThread); }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); List <Thread> threads = new List <Thread>(); for (int i = 0; i < 5; i++) { Thread T = new Thread(Worker); threads.Add(T); T.Start(); } using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { DateTime LastQueryTime = DateTime.Now; foreach (JobInfo job in repo.GetReadyJobs(JobSettings.MinPrepareTime)) { if (stoppingToken.IsCancellationRequested == true) { break; } if (repo.GetJob(job.Id).State == 0 && repo.AcquireJobLock(job.Id)) { if (job.RunAt > DateTime.Now) { await Task.Delay(job.RunAt - DateTime.Now); } queue.Add(job); } } if (stoppingToken.IsCancellationRequested == false && LastQueryTime.Add(JobSettings.MinPrepareTime) > DateTime.Now ) { await Task.Delay(LastQueryTime.Add(JobSettings.MinPrepareTime) - DateTime.Now); } } } queue.CompleteAdding(); threads.ForEach(T => { T.Join(); }); Console.WriteLine($"- shutdown event detected, stop worker service..."); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); List <Thread> threads = new List <Thread>(); for (int i = 0; i < threadCount; i++) { Thread T = new Thread(ProcessJob); threads.Add(T); T.Start(); } using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { foreach (var job in repo.GetReadyJobs()) { if (stoppingToken.IsCancellationRequested == true) { goto shutdown; } if (repo.GetJob(job.Id).State == (int)JobStateEnum.CREATE && repo.AcquireJobLock(job.Id)) { if (job.RunAt > DateTime.Now) { await Task.Delay(job.RunAt - DateTime.Now); } blockingCollection.Add(job); } } try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); } catch (TaskCanceledException) { break; } } } shutdown: this.blockingCollection.CompleteAdding(); foreach (var thread in threads) { thread.Join(); } Console.WriteLine($"End"); }
private static void Worker(object obj) { var index = (int)obj; JobInfo job; while (true) { if (jobList == null || jobList[index] == null || jobList[index].TryDequeue(out job) == false) { Thread.Sleep(20); continue; } if (job != null && job.RunAt <= DateTime.Now) { try { using (var repo = new JobsRepo()) { job = repo.GetJob(job.Id); if (job.State == 0 && repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("O"); } else { Console.Write("X"); } } } catch { Console.Write("E"); } } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); this._stop = stoppingToken; // init worker threads, 1 fetch, 5 process Thread[] threads = new Thread[_process_threads_count]; for (int i = 0; i < _process_threads_count; i++) { threads[i] = new Thread(this.ProcessThread); } foreach (var t in threads) { t.Start(); } // fetch Stopwatch timer = new Stopwatch(); Random rnd = new Random(); using (JobsRepo repo = new JobsRepo()) { while (true) { if (stoppingToken.IsCancellationRequested) { goto shutdown; } timer.Restart(); Console.WriteLine($"[T: {Thread.CurrentThread.ManagedThreadId}] fetch available jobs from repository..."); foreach (var job in repo.GetReadyJobs(JobSettings.MinPrepareTime)) { if (stoppingToken.IsCancellationRequested) { goto shutdown; } int predict_time = rnd.Next(300, 1700); if (job.RunAt - DateTime.Now > TimeSpan.FromMilliseconds(predict_time)) // 等到約一秒前,可以被取消。一秒內就先 LOCK { try { await Task.Delay(job.RunAt - DateTime.Now - TimeSpan.FromMilliseconds(predict_time), stoppingToken); } catch { goto shutdown; } } if (repo.GetJob(job.Id).State != 0) { continue; } if (repo.AcquireJobLock(job.Id) == false) { continue; } if (DateTime.Now < job.RunAt) { await Task.Delay(job.RunAt - DateTime.Now); } this._queue.Add(job); } try { await Task.Delay( (int)Math.Max((JobSettings.MinPrepareTime - timer.Elapsed).TotalMilliseconds, 0), stoppingToken); } catch { goto shutdown; } } shutdown: this._queue.CompleteAdding(); } foreach (var t in threads) { t.Join(); } Console.WriteLine($"[T: {Thread.CurrentThread.ManagedThreadId}] shutdown background services..."); }