protected override async Task ExecuteAsync(CancellationToken stoppingToken) { using (var repo = new JobsRepo()) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("RetrieveWorker running at: {time}", DateTimeOffset.Now); // get jobs into queue list // set duration with a delta time to compensate the delay time of various items var duration = (JobSettings.MinPrepareTime + JobSettings.MaxDelayTime).Add(new TimeSpan(0, 0, 0, -5, 0)); var jobs = repo.GetReadyJobs(duration).ToList(); _logger.LogWarning($"Retrieve job count: {jobs.Count}"); // remove duplicate items jobs.RemoveAll(x => Program.JobList.Select(i => i.Id).Contains(x.Id)); var obj = new object(); lock (obj) { Program.JobList.AddRange(jobs); } await Task.Delay(duration, stoppingToken).ConfigureAwait(false); } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { ThreadPool.SetMinThreads(MAX_CONCURRENT_SIZE, MAX_CONCURRENT_SIZE); Random random = new Random(); TimeSpan sleepSpan; double runAtRange = JobSettings.MinPrepareTime.TotalSeconds; for (int i = 0; i < MAX_CONCURRENT_SIZE; i++) { Task.Run(() => { JobWorker jobWorker = new JobWorker(MAX_CONCURRENT_SIZE); }); } await Task.Delay(1); using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { JobInfo tmpJobInfo = null; foreach (JobInfo job in repo.GetReadyJobs(TimeSpan.FromSeconds(runAtRange))) { Queue.push(job); //Console.WriteLine(job.Id + "\t" + job.RunAt); tmpJobInfo = job; } //計算SLEEP多久 if (tmpJobInfo == null) { sleepSpan = TimeSpan.FromMilliseconds((10 * 1000) + random.Next(5 * 1000)); //Console.WriteLine("[random]" + sleepSpan.Seconds + "\t" + sleepSpan.TotalSeconds); } else { sleepSpan = TimeSpan.FromSeconds((tmpJobInfo.RunAt.AddSeconds(random.Next(15)) - DateTime.Now).Seconds + 1); //Console.WriteLine("[next]" + sleepSpan.Seconds + "\t" + sleepSpan.TotalSeconds); } await Task.Delay(sleepSpan, stoppingToken); Console.Write("_"); } } }
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) { var channels = new List <Channel <JobInfo> >(); for (int i = 0; i < maxChannelNumber; i++) { var ch = Channel.CreateBounded <JobInfo>(new BoundedChannelOptions(1) { SingleWriter = true, SingleReader = true, AllowSynchronousContinuations = true }); channels.Add(ch); } foreach (var ch in channels) { DoJob(ch); } using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { var newJobs = repo.GetReadyJobs(TimeSpan.FromSeconds(10)).ToList(); foreach (var job in newJobs) { var done = false; while (!done) { foreach (var channel in channels) { var writer = channel.Writer; if (writer.WaitToWriteAsync(stoppingToken).Result) { writer.TryWrite(job); done = true; break; } } } } try { await Task.Delay(JobSettings.MinPrepareTime, stoppingToken); Console.Write("_"); } catch (TaskCanceledException) { break; } } } }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Delay(1, stoppingToken); using (var repo = new JobsRepo(_connectionString)) { while (stoppingToken.IsCancellationRequested == false) { JobInfo lastJobInThisRound = null; TimeSpan intervalSeconds = _defaultFetchJobsIntervalSeconds; Console.WriteLine("[Producer][FetchJobs]"); var jobs = repo.GetReadyJobs(_fetchJobsRunAtRange); foreach (var job in jobs) { if (stoppingToken.IsCancellationRequested) { goto shutdown; } Console.WriteLine($"[Producer][PutJobToQueue] #{job.Id} run at {job.RunAt}"); _stp.QueueUserWorkerItem(job); lastJobInThisRound = job; } try { if (lastJobInThisRound != null) { intervalSeconds = TimeSpan.FromSeconds((lastJobInThisRound.RunAt - DateTime.Now).Seconds + 1); Console.WriteLine($"[Producer][WaitForNextJob] {intervalSeconds.TotalSeconds} seconds"); } else { Console.WriteLine($"[Producer][Wait] {intervalSeconds.TotalSeconds} seconds"); } await Task.Delay(intervalSeconds, stoppingToken); } catch (TaskCanceledException) { _stp.Dispose(); break; } } } shutdown: Console.WriteLine("[System] In Levi's BackgroundService'"); Console.WriteLine("[System] 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"); }
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 async override Task ExecuteAsync(CancellationToken stoppingToken) { this._stop = stoppingToken; TimeSpan duration = JobSettings.MinPrepareTime + JobSettings.MaxDelayTime; using (JobsRepo repo = new JobsRepo()) { while (true) { readyJobs = repo.GetReadyJobs(duration).Where(x => x.LockAt == null).ToList(); Program.JobList.AddRange(readyJobs); try { Console.WriteLine("---------- GetJobsList ----------"); await Task.Delay(duration, stoppingToken); } catch (TaskCanceledException) { break; } } } }
protected async override Task ExecuteAsync(CancellationToken stoppingToken) { ThreadPool.SetMaxThreads(5, 5); ThreadPool.QueueUserWorkItem(Worker, 0); ThreadPool.QueueUserWorkItem(Worker, 1); ThreadPool.QueueUserWorkItem(Worker, 2); ThreadPool.QueueUserWorkItem(Worker, 3); ThreadPool.QueueUserWorkItem(Worker, 4); using (JobsRepo repo = new JobsRepo()) { while (stoppingToken.IsCancellationRequested == false) { var newJob = repo.GetReadyJobs(TimeSpan.FromSeconds(15)).ToList(); jobList = getCleanDictionary(); for (int i = 0; i < newJob.Count; i++) { jobList[i % 5].Enqueue(newJob[i]); } try { await Task.Delay(5000, 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); 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 void FetchJob() { while (_stop == false) { using (JobsRepo repo = new JobsRepo(_connectString)) { var jobs = repo.GetReadyJobs(TimeSpan.FromSeconds(_intervalSecond)); foreach (var job in jobs.OrderBy(X => X.RunAt)) { this._jobList.Add(job); Console.WriteLine(job.Id); } _doJobAre.Set(); _doJobAre.Reset(); } Task.WaitAny(Task.Delay(TimeSpan.FromSeconds(_intervalSecond)), Task.Run(() => _stopAre.WaitOne())); } }
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("_"); } } }