示例#1
0
        /// <summary>
        /// Create a new thread pool. number of threads in the pool can be smaller
        /// than maximum number of simultaneously placed job. Burst of new jobs can be
        /// served by small number of threads
        /// </summary>
        /// <param name="name">
        /// A <see cref="System.String"/>
        /// Name of the thread pool as it appears in debug reports
        /// </param>
        /// <param name="threads">
        /// A <see cref="System.Int32"/>
        /// Number of service threads
        /// </param>
        /// <param name="jobs">
        /// A <see cref="System.Int32"/>
        /// Maximum number of pending (yet to be served) jobs. The maximum number of jobs
        /// can larger than number of service threads
        /// </param>
        /// <param name="priority">
        /// A <see cref="Thread.Priority"/>
        /// Priority of the service threads
        /// </param>
        public ThreadPool(string name, int threads, int jobs, System.Threading.ThreadPriority priority)
        {
            this.Name           = name;
            this.Threads        = threads;
            this.Jobs           = jobs;
            MinThreadsFree      = threads;
            countStart          = 0;
            countDone           = 0;
            countMaxJobs        = 0;
            countRunningThreads = 0;

            jobThreads     = new Stack <JobThread>(threads);
            runningThreads = new List <JobThread>(threads);
            for (int i = 0; i < threads; i++)
            {
                JobThread jobThread = new JobThread(this, priority);
                jobThreads.Push(jobThread);
            }

            pendingJobs = new Queue <JobParams>(this.Jobs);
            freeJobs    = new Stack <JobParams>(this.Jobs);
            for (int i = 0; i < this.Jobs; i++)
            {
                JobParams jobParams = new JobParams();
                freeJobs.Push(jobParams);
            }

            // add myself to the list of created thread pools
            Resources.ThreadPools.Add(this);
        }
示例#2
0
        /// <summary>
        /// 获取JobThread
        /// </summary>
        /// <returns>true表示新创建的线程,否则表示原有的</returns>
        public bool GetJobThread(TriggerParam triggerParam, out JobThread jobThread)
        {
            lock (_syncObject)
            {
                if (_jobThreads.TryGetValue(triggerParam.jobId, out jobThread))
                {
                    if (jobThread.Stopped)
                    {
                        jobThread = CreateJobThread(triggerParam.jobId);
                        return(true);
                    }

                    if (jobThread.IsRunningOrHasQueue() && Constants.ExecutorBlockStrategy.COVER_EARLY == triggerParam.executorBlockStrategy)
                    {
                        jobThread.Interrupt("block strategy effect:" + triggerParam.executorBlockStrategy);
                        jobThread = CreateJobThread(triggerParam.jobId);
                        return(true);
                    }

                    return(false);
                }
                else
                {
                    jobThread = CreateJobThread(triggerParam.jobId);
                    return(true);
                }
            }
        }
示例#3
0
 /// <summary>
 /// return the service thread to the stack of free threads
 /// this method is called from the service thread
 /// </summary>
 protected void JobThreadDone(JobThread jobThread)
 {
     lock (jobThreads)
     {
         countDone++;
         runningThreads.Remove(jobThread);
         jobThreads.Push(jobThread);
     }
 }
示例#4
0
        private ReturnT IdleBeat(int jobId)
        {
            JobThread jobThread = _jobThreadFactory.FindJobThread(jobId);

            if (jobThread != null && jobThread.IsRunningOrHasQueue())
            {
                return(ReturnT.CreateFailedResult("job thread is running or has trigger queue."));
            }
            return(ReturnT.SUCCESS);
        }
示例#5
0
 /// <inheritdoc />
 protected override void StopFunction()
 {
     _stop.Set();
     JobThread.Join();
     foreach (var worker in _workers)
     {
         worker.Join();
     }
     _listener.Stop();
 }
        public ReturnT <String> kill(int jobId)
        {
            // kill handlerThread, and create new one
            JobThread jobThread = XxlJobExecutor.loadJobThread(jobId);

            if (jobThread != null)
            {
                XxlJobExecutor.removeJobThread(jobId, "人工手动终止");
                return(ReturnT <string> .SUCCESS);
            }

            return(new ReturnT <String>(ReturnT <string> .SUCCESS_CODE, "job thread aleady killed."));
        }
    public void Start()
    {
        if (jobs_started)
        {
            return;
        }
        jobs_started = true;

        for (int i = 0; i < threads.Length; i++)
        {
            threads[i] = new JobThread();
            threads[i].Start();
        }
    }
示例#8
0
        /// <summary>
        /// start a service thread if there are free service threads
        /// </summary>
        protected void RefreshQueue()
        {
            bool      shouldSpawnJob;
            JobThread jobThread = default(JobThread);

            do
            {
                shouldSpawnJob = (countRunningThreads == 0);

                // there are some running threads
                // I can get out - one of the running threads will serve
                // queue of pending jobs
                if (!shouldSpawnJob)
                {
                    break;
                }

                lock (jobThreads)
                {
                    if (jobThreads.Count > 0)
                    {
                        jobThread = jobThreads.Pop();
                        runningThreads.Add(jobThread);
                        MinThreadsFree = Math.Min(MinThreadsFree, jobThreads.Count);
                        countStart++;
                    }
                }

                // there is a free thread to serve the job
                // start the thread and get out
                if (jobThread != default(JobThread))
                {
                    jobThread.Start();
                    break;
                }

                lock (this)
                {
                    countFailedRefreshQueue++;
                }

                // i have to wait. there are no available threads and no thread is
                // running. should not be too long before a thread finishes
                Thread.Sleep(1);
            }while (true);
        }
        public ReturnT <String> idleBeat(int jobId)
        {
            // isRunningOrHasQueue
            bool      isRunningOrHasQueue = false;
            JobThread jobThread           = XxlJobExecutor.loadJobThread(jobId);

            if (jobThread != null && jobThread.isRunningOrHasQueue())
            {
                isRunningOrHasQueue = true;
            }

            if (isRunningOrHasQueue)
            {
                return(new ReturnT <String>(ReturnT <string> .FAIL_CODE, "job thread is running or has trigger queue."));
            }
            return(ReturnT <string> .SUCCESS);
        }
示例#10
0
        private void OnProcessJobs()
        {
            SaveConfig();

            if (_jobs.Count == 0)
            {
                LogWarning("No job in the list.");
                return;
            }

            if (!IsMEncoderPathValid(Config.MEncoderFilePath))
            {
                return;
            }

            if (_jobs.Count != _jobsListView.Items.Count)
            {
                LogError("The GUI and application job list count don't match. You should restart the application.");
                return;
            }

            Gui_OnJobStart();
            _jobsListView.Background = _jobsListViewBackground;

            if (JobThread != null)
            {
                JobThread.Join();
            }

            // Create a copy to be used only by the thread.
            var data = new JobsProcessThreadData();

            // ...

            JobThread = new Thread(JobsThread);
            JobThread.Start(data);
        }
示例#11
0
        private void AddJobs(List <string> filePaths, List <string> folderPaths)
        {
            if (filePaths.Count == 0 && folderPaths.Count == 0)
            {
                return;
            }

            Gui_OnJobStart();
            _jobsListView.Background = _jobsListViewBackground;

            if (JobThread != null)
            {
                JobThread.Join();
            }

            // Create a copy to be used only by the thread.
            var data = new JobAddThreadData();

            data.FilePaths.AddRange(filePaths);
            data.FolderPaths.AddRange(folderPaths);

            JobThread = new Thread(JobAddThread);
            JobThread.Start(data);
        }
        public ReturnT <String> run(TriggerParam triggerParam)
        {
            //// load old:jobHandler + jobThread
            JobThread   jobThread  = XxlJobExecutor.loadJobThread(triggerParam.jobId);
            IJobHandler jobHandler = jobThread != null?jobThread.getHandler() : null;

            String removeOldReason = null;

            switch (triggerParam.glueType)
            {
            case "BEAN":
            {
                IJobHandler newJobHandler = XxlJobExecutor.loadJobHandler(triggerParam.executorHandler);

                // valid old jobThread
                if (jobThread != null && jobHandler != newJobHandler)
                {
                    // change handler, need kill old thread
                    removeOldReason = "更换JobHandler或更换任务模式,终止旧任务线程";

                    jobThread  = null;
                    jobHandler = null;
                }

                // valid handler
                if (jobHandler == null)
                {
                    jobHandler = newJobHandler;
                    if (jobHandler == null)
                    {
                        return(new ReturnT <String>(ReturnT <string> .FAIL_CODE, "job handler [" + triggerParam.executorHandler + "] not found."));
                    }
                }
                break;
            }

            default:
            {
                return(new ReturnT <String>(ReturnT <string> .FAIL_CODE, "glueType[" + triggerParam.glueType + "] is not valid."));
            }
            }



            //// executor block strategy
            if (jobThread != null)
            {
                ExecutorBlockStrategyEnum blockStrategy = (ExecutorBlockStrategyEnum)Enum.Parse(typeof(ExecutorBlockStrategyEnum), triggerParam.executorBlockStrategy);
                if (ExecutorBlockStrategyEnum.DISCARD_LATER == blockStrategy)
                {
                    // discard when running
                    if (jobThread.isRunningOrHasQueue())
                    {
                        return(new ReturnT <String>(ReturnT <string> .FAIL_CODE, "阻塞处理策略-生效:" + ExecutorBlockStrategyEnum.DISCARD_LATER.ToString()));
                    }
                }
                else if (ExecutorBlockStrategyEnum.COVER_EARLY == blockStrategy)
                {
                    // kill running jobThread
                    if (jobThread.isRunningOrHasQueue())
                    {
                        removeOldReason = "阻塞处理策略-生效:" + ExecutorBlockStrategyEnum.COVER_EARLY.ToString();

                        jobThread = null;
                    }
                }
                else
                {
                    // just queue trigger
                }
            }

            // replace thread (new or exists invalid)
            if (jobThread == null)
            {
                jobThread = XxlJobExecutor.registJobThread(triggerParam.jobId, jobHandler, removeOldReason);
            }

            // push data to queue
            ReturnT <String> pushResult = jobThread.pushTriggerQueue(triggerParam);

            return(pushResult);
        }