我想设置一个TransformBlock
来并行处理其项目。因此,我将ExecutionDataflowBlockOptions.MaxDegreeOfParallelism
设置为>1。我不在乎消息的顺序,但是documentation表示:
“正确排序”是否意味着如果队列中有一条消息需要较长的处理时间,则在处理完这条消息之前不会再输出其他消息吗?
如果是这样,我如何指定不关心顺序的执行块(例如TransformBlock
)?还是我必须在消费端指定我不关心订购的商品?
最佳答案
库中没有这样的块,但是您可以通过组合ActionBlock
和BufferBlock
轻松地自己创建一个。就像是:
public static IPropagatorBlock<TInput, TOutput>
CreateUnorderedTransformBlock<TInput, TOutput>(
Func<TInput, TOutput> func, ExecutionDataflowBlockOptions options)
{
var buffer = new BufferBlock<TOutput>(options);
var action = new ActionBlock<TInput>(
async input =>
{
var output = func(input);
await buffer.SendAsync(output);
}, options);
action.Completion.ContinueWith(
t =>
{
IDataflowBlock castedBuffer = buffer;
if (t.IsFaulted)
{
castedBuffer.Fault(t.Exception);
}
else if (t.IsCanceled)
{
// do nothing: both blocks share options,
// which means they also share CancellationToken
}
else
{
castedBuffer.Complete();
}
});
return DataflowBlock.Encapsulate(action, buffer);
}
这样,一旦某个项目由
ActionBlock
处理,它就会立即移至BufferBlock
,这意味着将不保留排序。此代码的一个问题是,它不能很好地遵守
BoundedCapacity
设置:实际上,此块的容量是选项中设置的容量的两倍(因为两个块中的每个都有单独的容量)。关于c# - 如何使用TPL数据流库指定无序执行块?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22893908/