public static IPropagatorBlock<TInput, TOutput> Encapsulate<TInput, TOutput>(
ITargetBlock<TInput> target,
ISourceBlock<TOutput> source)
为了让您能够将多个块封装到一个转换块中,它能够返回一个
IPropagatorBlock<TInput, TOutput>
这代表着你的管道的起始和结束块。
然而,如果我的管道中最后一个块是ActionBlock,我就不能使用它,因为ActionBlock不是SourceBlock,函数的返回类型将是ITargetBlock,而不是IPropagatorBlock。
本质上,我正在寻找类似于以下的函数:
public static ITargetBlock<TStart> Encapsulate<TStart, TEnd>(
ITargetBlock<TStart> startBlock,
ActionBlock<TEnd> endBlock)
这是一个明智的写法,还是我错过了一些简单的东西?我不太确定如何写它 - 特别是完成部分的接线。我需要创建自己的自定义块类型吗?
编辑:
好的,所以读了@Panagiotis Kanavos的回答并进行了一些尝试,我想出了这个方案。这基于EncapsulatingPropagator类,这就是现有的DataflowBlock.Encapsulate方法使用的类。
internal sealed class EncapsulatingTarget<TStart, TEnd> : ITargetBlock<TStart>
{
private readonly ITargetBlock<TStart> startBlock;
private readonly ActionBlock<TEnd> endBlock;
public EncapsulatingTarget(ITargetBlock<TStart> startBlock, ActionBlock<TEnd> endBlock)
{
this.startBlock = startBlock;
this.endBlock = endBlock;
}
public Task Completion
{
get { return this.endBlock.Completion; }
}
public void Complete()
{
this.startBlock.Complete();
}
void IDataflowBlock.Fault(Exception exception)
{
if (exception == null)
{
throw new ArgumentNullException("exception");
}
this.startBlock.Fault(exception);
}
public DataflowMessageStatus OfferMessage(
DataflowMessageHeader messageHeader,
TStart messageValue,
ISourceBlock<TStart> source,
bool consumeToAccept)
{
return this.startBlock.OfferMessage(messageHeader, messageValue, source, consumeToAccept);
}
}