Пример #1
0
            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...");
        }
Пример #4
0
        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");
        }
Пример #5
0
            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");
                        }
                    }
                }
            }
Пример #6
0
        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...");
        }