예제 #1
0
        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;
                    }
                }
            }
        }
예제 #2
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...");
        }
예제 #5
0
파일: Worker.cs 프로젝트: pk2400178/CSharp
        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");
        }
예제 #6
0
 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....");
                 }
             }
         }
     }
 }
예제 #7
0
        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...");
        }
예제 #8
0
        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...");
        }
예제 #9
0
        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);
                }
            }
        }
예제 #10
0
        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()));
            }
        }
예제 #11
0
        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; }
                }
            }
        }
예제 #12
0
        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; }
                }
            }
        }
예제 #13
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");
                        }
                    }
                }
            }
예제 #14
0
        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.");
        }
예제 #15
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...");
        }
        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("_");
                }
            }
        }