9

優先的に実装したいActionBlock<T>TInputを使用して、条件付きで一部のアイテムを優先できるようにしPredicate<T>ます。Parallel Extensions Extras SamplesGuide to Implementing Custom TPL Dataflow Blocks
を読み ました。 しかし、このシナリオをどのように実装できるかまだわかりません。 - - - - - - - - - - - - - - 編集 - - - - - - - - - - - ------ いくつかのタスクがあり、そのうちの 5 つを同時に実行できます。ユーザーがボタンを押すと、いくつかの (述語関数に依存する) タスクが最も優先度が高く実行されます。 実際、私はこのコードを書きます



TaskScheduler taskSchedulerHighPriority;
ActionBlock<CustomObject> actionBlockLow;
ActionBlock<CustomObject> actionBlockHigh;
...
queuedTaskScheduler = new QueuedTaskScheduler(TaskScheduler.Default, 5);
taskSchedulerHigh = queuedTaskScheduler.ActivateNewQueue(0);
taskSchedulerLow = queuedTaskScheduler.ActivateNewQueue(1);
...
actionBlockHigh = new ActionBlock<CustomObject>(new Action<CustomObject>(method), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5, SingleProducerConstrained = false, TaskScheduler = taskSchedulerHigh });
actionBlockLow = new ActionBlock<CustomObject>(new Action<CustomObject>(method), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5, MaxMessagesPerTask = 1, TaskScheduler = taskSchedulerLow });
...     
if (predicate(customObject))
    actionBlockHigh.Post(customObject);
else
    actionBlockLow.Post(customObject);

しかし、優先権はまったく有効にならないようです。
---------------------------- 編集 ------------------
私はこのコード行を使用すると、

actionBlockHigh = new ActionBlock<AvlHistory>(new Action<AvlHistory>(SemaphoreAction), new ExecutionDataflowBlockOptions { TaskScheduler = taskSchedulerHigh });
actionBlockLow = new ActionBlock<AvlHistory>(new Action<AvlHistory>(SemaphoreAction), new ExecutionDataflowBlockOptions { TaskScheduler = taskSchedulerLow });

アプリケーションはタスクの優先度を正しく監視しますが、一度に実行できるタスクは 1 つだけです。一方、フローに示されている最初のコード ブロックを使用すると、アプリケーションは 5 つのタスクを同時に実行しますが、不適切な優先順位になります。

actionBlockHigh = new ActionBlock<AvlHistory>(new Action<AvlHistory>(SemaphoreAction), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5, TaskScheduler = taskSchedulerHigh });
actionBlockLow = new ActionBlock<AvlHistory>(new Action<AvlHistory>(SemaphoreAction), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 5, TaskScheduler = taskSchedulerLow });

更新:
svick へのタンク、指定する必要がありMaxMessagesPerTaskますtaskSchedulerLow

4

1 に答える 1

8

あなたの質問には多くの詳細が含まれていないため、以下は必要なものの推測に過ぎません。

これを行う最も簡単な方法は、 ParallelExtensionsExtras からActionBlock異なる優先度で実行される2 つの を用意することだと思います。述語を使用して優先順位の高いものにリンクしてから、優先順位の低いものにリンクします。また、優先度の高いs が待機していないことを確認するために、優先度の低いブロックを設定します。QueuedTaskSchedulerTaskMaxMessagesPerTask

コードでは、次のようになります。

static ITargetBlock<T> CreatePrioritizedActionBlock<T>(
    Action<T> action, Predicate<T> isPrioritizedPredicate)
{
    var buffer = new BufferBlock<T>();

    var scheduler = new QueuedTaskScheduler(1);

    var highPriorityScheduler = scheduler.ActivateNewQueue(0);
    var lowPriorityScheduler = scheduler.ActivateNewQueue(1);

    var highPriorityBlock = new ActionBlock<T>(
        action, new ExecutionDataflowBlockOptions
        {
            TaskScheduler = highPriorityScheduler
        });
    var lowPriorityBlock = new ActionBlock<T>(
        action, new ExecutionDataflowBlockOptions
        {
            TaskScheduler = lowPriorityScheduler,
            MaxMessagesPerTask = 1
        });

    buffer.LinkTo(highPriorityBlock, isPrioritizedPredicate);
    buffer.LinkTo(lowPriorityBlock);

    return buffer;
}

これは、たとえば、Completion返されたブロックが正しく動作しないなど、できることの単なるスケッチです。

于 2012-12-14T22:17:05.670 に答える