C# 定制ActionBlock<;T>;
我想实现一个优先的C# 定制ActionBlock<;T>;,c#,multithreading,task-parallel-library,.net-4.5,tpl-dataflow,C#,Multithreading,Task Parallel Library,.net 4.5,Tpl Dataflow,我想实现一个优先的操作块。因此,我可以通过使用谓词有条件地优先考虑一些TInput项 我阅读和阅读。 但是仍然不知道如何实现这个场景。 ----------------------------编辑------------------------------------------ 有一些任务,其中5个可以同时运行。当用户按下按钮时,某些(取决于谓词函数)任务应以最高优先级运行。 事实上,我写了这段代码 TaskScheduler taskSchedulerHighPriority; Action
操作块
。因此,我可以通过使用谓词有条件地优先考虑一些TInput
项
我阅读和阅读。
但是仍然不知道如何实现这个场景。
----------------------------编辑------------------------------------------
有一些任务,其中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);
TaskScheduler taskSchedulerHighPriority;
ActionBlock actionBlockLow;
动作块动作块高;
...
queuedTaskScheduler=新的queuedTaskScheduler(TaskScheduler.Default,5);
taskSchedulerHigh=queuedTaskScheduler.ActivateNewQueue(0);
taskSchedulerLow=queuedTaskScheduler.ActivateNewQueue(1);
...
actionBlockHigh=new ActionBlock(新操作(方法),new ExecutionDataflowBlockOptions{MaxDegreeOfParallelism=5,SingleProducerConstrained=false,TaskScheduler=TaskScheduleRigh});
actionBlockLow=new ActionBlock(新操作(方法),新ExecutionDataflowBlockOptions{MaxDegreeOfParallelism=5,MaxMessagesPerTask=1,TaskScheduler=taskSchedulerLow});
...
if(谓词(自定义对象))
actionBlockHigh.Post(customObject);
其他的
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 });
actionBlockHigh=newactionblock(新动作(信号量动作),新ExecutionDataflowBlockOptions{TaskScheduler=taskSchedulerHigh});
actionBlockLow=new ActionBlock(新操作(信号量处理),new ExecutionDataflowBlockOptions{TaskScheduler=taskSchedulerLow});
导致应用程序正确观察任务的优先级,但一次只能执行一个任务,同时使用流程中显示的第一个代码块,导致应用程序同时运行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 });
actionBlockHigh=newactionblock(新操作(信号量处理),新ExecutionDataflowBlockOptions{MaxDegreeOfParallelism=5,taskSchedulerHigh});
actionBlockLow=new ActionBlock(新操作(信号量处理),new ExecutionDataflowBlockOptions{MaxDegreeOfParallelism=5,TaskScheduler=taskSchedulerLow});
更新:
对于svick,我应该为taskSchedulerLow
指定MaxMessagesPerTask
,您的问题没有包含很多细节,因此下面只是您可能需要的猜测
我认为最简单的方法是让两个ActionBlock
s以不同的优先级运行。您可以使用谓词链接到高优先级,然后链接到低优先级。另外,为了确保高优先级任务
没有等待,请设置低优先级块的MaxMessagesPerTask
在代码中,它看起来像:
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;
}
静态ITargetBlock CreatePriorityDactionBlock(
动作,谓词isPrioritizedPredicate)
{
var buffer=new BufferBlock();
var调度程序=新的QueuedTaskScheduler(1);
var highPriorityScheduler=scheduler.ActivateNewQueue(0);
var lowPriorityScheduler=scheduler.ActivateNewQueue(1);
var highPriorityBlock=新操作块(
操作,新的ExecutionDataflowBlockOptions
{
TaskScheduler=highPriorityScheduler
});
var lowPriorityBlock=新动作块(
操作,新的ExecutionDataflowBlockOptions
{
TaskScheduler=lowPriorityScheduler,
MaxMessagesPerTask=1
});
buffer.LinkTo(highPriorityBlock,ispriorityedpredicate);
缓冲区链接到(低优先级块);
返回缓冲区;
}
这只是您可以执行的操作的示意图,例如,返回块的
完成操作不正确。什么决定了优先级?它与T
完全无关吗?或者优先级是T
的固有/派生属性?您可以创建使用ConcurrentPriorityQueue的自定义缓冲区块,也可以创建自定义异步转换块。这两种选择都很重要。同样同意@casperOne,优先级在您的情况下意味着什么?在代码中,您没有为低优先级块指定MaxMessagesPerTask
。正如我所说,这样做是非常重要的。