Question

I want to get the current executing Task that I am adding in the blockingqueue, how it can be done?

EDIT: I am using this priority scheduler, and adding multiple tasks with different priorities:

public class PriorityScheduler : TaskScheduler
{
    public static PriorityScheduler Highest = new PriorityScheduler(ThreadPriority.Highest);
    public static PriorityScheduler AboveNormal = new PriorityScheduler(ThreadPriority.AboveNormal);
    public static PriorityScheduler Normal = new PriorityScheduler(ThreadPriority.Normal);
    public static PriorityScheduler BelowNormal = new PriorityScheduler(ThreadPriority.BelowNormal);
    public static PriorityScheduler Lowest = new PriorityScheduler(ThreadPriority.Lowest);

    public static BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
    private Thread[] _threads;
    private ThreadPriority _priority;
    private readonly int _maximumConcurrencyLevel = Math.Max(1, Environment.ProcessorCount);

    public PriorityScheduler(ThreadPriority priority)
    {
        _priority = priority;
    }

    public override int MaximumConcurrencyLevel
    {
        get { return _maximumConcurrencyLevel; }
    }

    protected override IEnumerable<Task> GetScheduledTasks()
    {
        return _tasks;
    }

    protected override void QueueTask(Task task)
    {
        _tasks.Add(task);

        if (_threads == null)
        {
            _threads = new Thread[_maximumConcurrencyLevel];
            for (int i = 0; i < _threads.Length; i++)
            {
                int local = i;
                _threads[i] = new Thread(() =>
                {
                    foreach (Task t in _tasks.GetConsumingEnumerable())
                        base.TryExecuteTask(t);
                });
                _threads[i].Name = string.Format("PriorityScheduler: ", i);
                _threads[i].Priority = _priority;
                _threads[i].IsBackground = true;
                _threads[i].Start();
            }
        }
    }

    protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
    {
        return false; // we might not want to execute task that should schedule as high or low priority inline
    }
}

I want to stop and resume tasks depending upon there priorities, e.g. if a new task with higher priority arrives, the lower stops and lets the task execute and then resumes itself...

Was it helpful?

Solution

If you are referring to BlockingCollection<T>, you can't (directly). When you call Take() (or get the next item via GetConsumingEnumerable()), the item (task?) is actually removed from the underlying connection.

You would need to have your consumer store and expose the "current task" if you want this to be available.

Note that the Parallel Extension Extras project provides a great QueuedTaskScheduler which may accomplish your goals here. It allows you to create prioritized TaskScheduler instances, and handles all of the scheduling for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top