Ich möchte eine priorisierte ActionBlock<T>
implementieren. So dass ich einige TInput
Elemente mit einer Predicate<T>
bedingt Priorität geben kann.
Ich lese Parallel Extensions Extras Samples und Guide to Implementing Custom TPL Dataflow Blocks.
Aber immer noch nicht herausfinden, wie kann ich dieses Szenario implementieren.
---------------------------- BEARBEITEN ------------------- --------
Es gibt einige Aufgaben, von denen 5 gleichzeitig ausgeführt werden können. Wenn Benutzer die Schaltfläche drücken, sollten einige (abhängig von der Prädikatfunktion) mit der höchsten Priorität ausgeführt werden.
Tatsächlich schreibe ich diesen CodeAnpassen ActionBlock <T>
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);
Aber es scheint Priorität überhaupt bewirkt nicht statt.
---------------------------- BEARBEITEN ------------------
finde ich die Tatsache, dass, wenn ich diese Codezeile verwenden:
actionBlockHigh = new ActionBlock<AvlHistory>(new Action<AvlHistory>(SemaphoreAction), new ExecutionDataflowBlockOptions { TaskScheduler = taskSchedulerHigh });
actionBlockLow = new ActionBlock<AvlHistory>(new Action<AvlHistory>(SemaphoreAction), new ExecutionDataflowBlockOptions { TaskScheduler = taskSchedulerLow });
Ursache Anwendung korrekt Prioritäten der Tasks beobachten, sondern nur eine Aufgabe zu einer Zeit werden, ausführen kann, inzwischen den ersten Codeblock verwenden, die in gezeigt wird fließend, weil die Anwendung 5 Tasks gleichzeitig, aber in unangemessener Reihenfolge ausführt.
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 });
Update:
Tanks svick, i MaxMessagesPerTask
für taskSchedulerLow
angeben sollte.
Was diktiert die Priorität? Ist es etwas, das nicht mit "T" zusammenhängt? Oder ist die Priorität eine inhärente/abgeleitete Eigenschaft von 'T'? – casperOne
Sie können einen benutzerdefinierten Pufferblock erstellen, der eine ConcurrentPriorityQueue verwendet, oder Sie können einen benutzerdefinierten asynchronen Transfomationsblock erstellen. Beide Optionen sind nicht trivial. Stimmen Sie auch mit @ casperOne überein, was bedeutet Priorität in Ihrem Fall? –