Exemplo n.º 1
0
    /// <summary>
    /// Do the actual work in processing a task in the queue
    /// </summary>
    /// <param name="job"></param>
    /// <param name="cpuPercentage"></param>
    /// <returns></returns>
    private void ProcessJob(IProcessJob job, int cpuPercentage)
    {
        // If we can't process, we'll discard this job, and pick it
        // up again in future during the next GetPendingJobs call.
        if (job.CanProcess)
        {
            string jobName = job.GetType().Name;

            SetStatus($"{job.Name}", JobStatus.Running, cpuPercentage);

            Logging.LogVerbose($"Processing job type: {jobName}");

            Stopwatch stopwatch = new Stopwatch($"ProcessJob{jobName}");
            try
            {
                job.Process();
            }
            catch (Exception ex)
            {
                Logging.LogError($"Exception processing {job.Description}: {ex.Message}");
            }
            finally
            {
                stopwatch.Stop();
            }

            // Now, decide how much we need to sleep, in order to throttle CPU to the desired percentage
            // E.g., if the job took 2.5s to execute, then in order to maintain 25% CPU usage, we need to
            // sleep for 7.5s. Similarly, if the job took 0.5s, and we want to maintain 75% CPU usage,
            // we'd sleep for 0.33s.
            double sleepFactor = (1.0 / (cpuPercentage / 100.0)) - 1;

            if (sleepFactor > 0)
            {
                // Never ever sleep for more than 10s. Otherwise a long-running job that takes a minute
                // to complete could end up freezing the worker thread for 3 minutes, which makes no
                // sense whatsoeever. :)
                const int maxWaitTime = 10 * 1000;
                int       waitTime    = Math.Min((int)(sleepFactor * stopwatch.ElapsedTime), maxWaitTime);
                Logging.LogVerbose($"Job '{jobName}' took {stopwatch.ElapsedTime}ms, so sleeping {waitTime} to give {cpuPercentage}% CPU usage.");
                Thread.Sleep(waitTime);
            }
        }
    }