我想设置一个TransformBlock来并行处理其项目。因此,我将ExecutionDataflowBlockOptions.MaxDegreeOfParallelism设置为>1。我不在乎消息的顺序,但是documentation表示:



“正确排序”是否意味着如果队列中有一条消息需要较长的处理时间,则在处理完这条消息之前不会再输出其他消息吗?

如果是这样,我如何指定不关心顺序的执行块(例如TransformBlock)?还是我必须在消费端指定我不关心订购的商品?

最佳答案

库中没有这样的块,但是您可以通过组合ActionBlockBufferBlock轻松地自己创建一个。就像是:

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/

10-13 06:49