private static async Task DoJob(ChannelReader <JobInfo> reader) { using (JobsRepo repo = new JobsRepo()) { while (await reader.WaitToReadAsync()) { while (reader.TryRead(out JobInfo job)) { Task.Run(async() => { var now = DateTime.Now; if (job.RunAt > now) { await Task.Delay(job.RunAt.Subtract(now)); } if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.WriteLine("O"); } else { Console.WriteLine("X"); } }).Wait(); } if (reader.Completion.IsCompleted) { break; } } } }
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 void RunThread() { using (JobsRepo repo = new JobsRepo()) { foreach (var job in readyJobs) { if (job.State == 0 && repo.AcquireJobLock(job.Id)) { if (repo.ProcessLockedJob(job.Id)) { Console.WriteLine($"[job ID: {job.Id}] update state...."); } } } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { bool empty = true; foreach (var job in repo.GetReadyJobs()) { if (stoppingToken.IsCancellationRequested == true) { goto shutdown; } if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("O"); } else { Console.Write("X"); } empty = false; } if (empty == false) { continue; } try { await Task.Delay(10000, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } shutdown: Console.WriteLine($"- shutdown event detected, stop worker service..."); }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); using (JobsRepo repo = new JobsRepo("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=D:\\workspace\\dotnet\\SchedulingPractice\\SubWorker.AndrewDemo\\JobsDB.mdf;Integrated Security=True")) { while (stoppingToken.IsCancellationRequested == false) { bool empty = true; foreach (var job in repo.GetReadyJobs()) { if (stoppingToken.IsCancellationRequested == true) { goto shutdown; } if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("O"); } else { Console.Write("X"); } empty = false; } if (empty == false) { continue; } try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } shutdown: Console.WriteLine($"- shutdown event detected, stop worker service..."); }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { using (var repo = new JobsRepo()) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("ExecuteWorker running at: {time}", DateTimeOffset.Now); // get all jobs need to be process from JobList var readyJobs = Program.JobList.Where(x => (DateTime.Now - x.RunAt) > new TimeSpan(0, 0, 0, 0, JobSettings.LoopDuration)).ToList(); if (readyJobs.Count > 0) { _logger.LogWarning($"Current execute job count: {readyJobs.Count}"); } // process all jobs by using Task.Run foreach (JobInfo job in readyJobs) { //Task.Run(() => //{ var isLock = repo.AcquireJobLock(job.Id); if (isLock) { repo.ProcessLockedJob(job.Id); } //}); } var obj = new object(); lock (obj) { Program.JobList.RemoveAll(x => readyJobs.Select(i => i.Id).Contains(x.Id)); } await Task.Delay(JobSettings.LoopDuration, stoppingToken).ConfigureAwait(false); } } }
private void ExuteBody() { while (_stop == false) { JobInfo job = null; while (this._jobList.TryTake(out job)) { if (job.RunAt > DateTime.Now) { var sleepTime = job.RunAt.Subtract(DateTime.Now); int index = Task.WaitAny( Task.Delay(sleepTime), Task.Run(() => _stopAre.WaitOne())); if (index == 1) { break; } } using (JobsRepo repo = new JobsRepo(this._connectString)) { if (repo.AcquireJobLock(job.Id)) { repo.ProcessLockedJob(job.Id); Console.Write("O"); } else { Console.Write("X"); } } } Task.WaitAny( Task.Run(() => _stopAre.WaitOne()), Task.Run(() => _doJobAre.WaitOne())); } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); this._stop = stoppingToken; TimeSpan duration = JobSettings.ExecuteDuration; using (JobsRepo repo = new JobsRepo()) { while (true) { readyJobs = Program.JobList; while (readyJobs.Count > 0) { var jobs = readyJobs.Where(x => x.RunAt <= DateTime.Now).ToList(); foreach (var job in jobs) { if (job.State == 0 && repo.AcquireJobLock(job.Id)) { if (repo.ProcessLockedJob(job.Id)) { Console.WriteLine($"[job ID: {job.Id}] update state...."); readyJobs.Remove(job); } } } Program.JobList.RemoveAll(x => jobs.Select(y => y.Id).Contains(x.Id)); } //try //{ // Console.WriteLine("---------- Delay ----------"); // await Task.Delay(duration, stoppingToken); //} //catch (TaskCanceledException) { break; } } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1); this._stop = stoppingToken; using (JobsRepo repo = new JobsRepo()) { while (true) { readyJobs = repo.GetReadyJobs(JobSettings.MinPrepareTime).ToList(); foreach (var job in readyJobs) { if (job.State == 0 && repo.AcquireJobLock(job.Id)) { if (repo.ProcessLockedJob(job.Id)) { Console.WriteLine($"[job ID: {job.Id}] update state...."); } } } //Thread[] threads = new Thread[threadsCnts]; //for (int i = 0; i < threadsCnts; i++) //{ // threads[i] = new Thread(RunThread); // threads[i].Start(); //} try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } }
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) { var threads = Enumerable.Range(1, ThreadCnt).Select(tid => new Thread(() => { using (JobsRepo jr = new JobsRepo()) { while (!_queue.IsCompleted) { JobInfo job = null; try { Console.WriteLine($"Thread({tid}) is waiting for a job..."); _queue.TryTake(out job, 3000); } catch (OperationCanceledException ex) { Console.WriteLine($"Thread({tid}) stopped waiting for a job..."); } if (job != null) { var diff = (int)(job.RunAt - DateTime.Now).TotalMilliseconds; if (diff > 0) { Console.WriteLine($"Thread({tid}) is waiting to run job({job.Id})..."); Thread.Sleep(diff); } Console.WriteLine($"Thread({tid}) is running job({job.Id})..."); jr.ProcessLockedJob(job.Id); Console.WriteLine($"Thread({tid}) processed job({job.Id})."); //Console.Write("O"); } } } })).ToArray(); foreach (var t in threads) { t.Start(); } using (JobsRepo repo = new JobsRepo()) { while (true) { foreach (var job in repo.GetReadyJobs(JobSettings.MinPrepareTime)) { if (stoppingToken.IsCancellationRequested) { break; } if (repo.AcquireJobLock(job.Id)) { _queue.Add(job); } } if (stoppingToken.IsCancellationRequested) { break; } try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); } catch (TaskCanceledException ex) { } catch (OperationCanceledException ex) { } } } _queue.CompleteAdding(); Console.WriteLine($"- shutdown event detected, stop worker service..."); Console.WriteLine($"- queued job count({_queue.Count}) before"); await Task.Run(() => { foreach (var t in threads) { t.Join(); } }); Console.WriteLine($"- queued job count({_queue.Count}) after"); Console.WriteLine($"- worker service stopped."); }
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..."); }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { ThreadPool.SetMinThreads(MAX_CONCURRENT_SIZE, MAX_CONCURRENT_SIZE); for (int i = 0; i < MAX_CONCURRENT_SIZE; i++) { Task.Run(() => { JobWorker jobWorker = new JobWorker(MAX_CONCURRENT_SIZE); }); } await Task.Delay(1); TimeSpan sleepSpan; using (JobsRepo repo = new JobsRepo("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=D:\\workspace\\dotnet\\SchedulingPractice\\SubWorker.AndrewDemo\\JobsDB.mdf;Integrated Security=True")) { while (stoppingToken.IsCancellationRequested == false) { JobInfo tmpJobInfo = null; foreach (JobInfo job in repo.GetReadyJobs()) { if (repo.AcquireJobLock(job.Id)) { Console.Write("O"); Queue.push(job); Console.WriteLine(job.Id + "\t" + job.RunAt); tmpJobInfo = job; } else { Console.Write("X"); } } //計算SLEEP多久 if (tmpJobInfo == null) { Random random = new Random(); sleepSpan = TimeSpan.FromMilliseconds((10 * 1000) + random.Next(5 * 1000)); Console.WriteLine("[random]" + sleepSpan.Seconds + "\t" + sleepSpan.TotalSeconds); } else { sleepSpan = TimeSpan.FromSeconds((tmpJobInfo.RunAt.AddSeconds(10) - DateTime.Now).Seconds + 1); Console.WriteLine("[next]" + sleepSpan.Seconds + "\t" + sleepSpan.TotalSeconds); //Console.ReadKey(); //System.Environment.Exit(0); } //await Task.Delay(TimeSpan.FromSeconds(29), stoppingToken); await Task.Delay(sleepSpan, stoppingToken); //Console.ReadKey(); //System.Environment.Exit(0); Console.Write("_"); } } }