0

ブロッキングキューに追加している現在実行中のタスクを取得したいのですが、どのように行うことができますか?

編集:私はこの優先度スケジューラを使用しており、優先度の異なる複数のタスクを追加しています:

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
    }
}

優先度に応じてタスクを停止して再開したい。たとえば、優先度の高い新しいタスクが到着した場合、優先度の低いタスクが停止してタスクを実行し、再開します...

4

1 に答える 1

2

を参照している場合はBlockingCollection<T>、(直接) できません。呼び出すTake()(または を介し​​て次のアイテムを取得するGetConsumingEnumerable()) と、アイテム (タスク?) は実際には基になる接続から削除されます。

これを利用可能にしたい場合は、消費者ストアを用意して「現在のタスク」を公開する必要があります。

Parallel Extension Extrasプロジェクトは、ここでの目標を達成できる優れたQueuedTaskSchedulerを提供することに注意してください。優先度の高いインスタンスを作成しTaskScheduler、すべてのスケジューリングを処理できます。

于 2012-10-05T21:11:54.140 に答える