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)); }
/// <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)); } }
public PriorityTaskScheduler(Channel <Task> channel, TaskSchedulerPriority priority) { _channel = channel; _priority = priority; }
/// <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); }