public JoinableTask <T> RunAsync <T>(TaskSchedulerPriority priority, Func <System.Threading.Tasks.Task <T> > asyncMethod)
        {
            // Only support UI background at the moment, we can add more when needed
            if (priority != TaskSchedulerPriority.UIThreadBackgroundPriority)
            {
                throw new ArgumentOutOfRangeException(nameof(priority), priority, null);
            }

            return(ThreadHelper.JoinableTaskFactory.RunAsync(VsTaskRunContext.UIThreadBackgroundPriority, asyncMethod));
        }
示例#2
0
        /// <summary>
        /// Get highest possible TaskSchdeduler of requested priority
        /// </summary>
        /// <param name="priority">requested priority</param>
        /// <returns>TaskSchdeduler with highest possible priority</returns>
        /// <exception cref="ArgumentException">priority not supported</exception>
        public TaskScheduler GetScheduler(TaskSchedulerPriority priority)
        {
            switch (priority)
            {
            case TaskSchedulerPriority.Normal:
                return(_normalScheduler);

            case TaskSchedulerPriority.Realtime:
            case TaskSchedulerPriority.High:
            case TaskSchedulerPriority.AboveNormal:
                return(_highScheduler);

            case TaskSchedulerPriority.BelowNormal:
            case TaskSchedulerPriority.Low:
                return(_lowScheduler);

            case TaskSchedulerPriority.Background:
                //case TaskSchedulerPriority.Idle:
                return(_idleScheduler);

            default:
                throw new ArgumentException(nameof(priority));
            }
        }
示例#3
0
 public PriorityTaskScheduler(Channel <Task> channel, TaskSchedulerPriority priority)
 {
     _channel  = channel;
     _priority = priority;
 }
示例#4
0
        /// <summary>
        /// work loop
        /// </summary>
        /// <param name="workerId">the worker id</param>
        /// <returns></returns>
        private int DoWork(int workerId)
        {
            var highCount   = 0; //executed work items in priority high
            var normalCount = 0; //executed work items in priority normal
            var lowCount    = 0; //executed work items in priority low
            var idleCount   = 0; //executed work items in priority idle

            int c;
            int rounds = 0;     //loop count
            int roundWork;      //work count in the current loop
            int roundClean = 0; //clean loop count

            //maybe implement max work count and/or a deadline


            //the work loop
            _threadPriority = TaskSchedulerPriority.Idle;
            try
            {
                do
                {
                    rounds++;
                    roundWork = 0;

                    //execute all high priority work
                    c          = _highScheduler.ExecuteAll();
                    highCount += c;
                    roundWork += c;

                    //execute normal priority work until max work count
                    c            = _normalScheduler.ExecuteMany(_maxWork);
                    normalCount += c;
                    roundWork   += c;

                    //only when all other priority queues where empty
                    //then execute multiple low priority work
                    c = roundWork > 0
                        ? _lowScheduler.ExecuteSingle()
                        : _lowScheduler.ExecuteMany(_maxWork);
                    lowCount  += c;
                    roundWork += c;

                    //only execute background tasks
                    //when the current loop executed no work items
                    if (c == 0)
                    {
                        c          = _idleScheduler.ExecuteSingle();
                        idleCount += c;
                        roundWork += c;
                    }

                    //count clean loops
                    roundClean = roundWork == 0 ? roundClean + 1 : 0;
                }while (roundClean < 2 && !_cts.IsCancellationRequested);
            }
            catch
            {
                //ignore error
            }
            finally
            {
                _threadPriority = TaskSchedulerPriority.None;
            }

            //worker stopped

            var total = highCount + normalCount + lowCount + idleCount;

            //todo push to metrics: workerId, total, highCount, normalCount, lowCount, idleCount
            //maybe add StopWatch

            return(total);
        }