为什么选择TPL数据流块.LinkTo 不提供任何输出
本文关键字:任何 输出 LinkTo 选择 TPL 数据流 为什么 | 更新日期: 2023-09-27 18:33:47
我对TPL数据流这个话题很陌生。在《C#中的并发》一书中,我测试了以下示例。我不知道为什么没有应该2*2-2=2
的输出;
static void Main(string[] args)
{
//Task tt = test();
Task tt = test1();
Console.ReadLine();
}
static async Task test1()
{
try
{
var multiplyBlock = new TransformBlock<int, int>(item =>
{
if (item == 1)
throw new InvalidOperationException("Blech.");
return item * 2;
});
var subtractBlock = new TransformBlock<int, int>(item => item - 2);
multiplyBlock.LinkTo(subtractBlock,
new DataflowLinkOptions { PropagateCompletion = true });
multiplyBlock.Post(2);
await subtractBlock.Completion;
int temp = subtractBlock.Receive();
Console.WriteLine(temp);
}
catch (AggregateException e)
{
// The exception is caught here.
foreach (var v in e.InnerExceptions)
{
Console.WriteLine(v.Message);
}
}
}
更新1:我尝试了另一个例子。我仍然没有使用Block.Complete()
但我认为当第一个块完成时,结果会自动传递到第二个块中。
private static async Task test3()
{
TransformManyBlock<int, int> tmb = new TransformManyBlock<int, int>((i) => { return new int[] {i, i + 1}; });
ActionBlock<int> ab = new ActionBlock<int>((i) => Console.WriteLine(i));
tmb.LinkTo(ab);
for (int i = 0; i < 4; i++)
{
tmb.Post(i);
}
//tmb.Complete();
await ab.Completion;
Console.WriteLine("Finished post");
}
这部分代码:
await subtractBlock.Completion;
int temp = subtractBlock.Receive();
首先(异步)等待减法块完成,然后尝试从该块检索输出。
有两个问题:源块从未完成,并且代码正在尝试从已完成的块中检索输出。一旦一个块完成,它将不会产生更多的数据。
(我假设您指的是配方 4.2 中的示例,该示例将发布1
,导致异常,从而在错误状态下完成块)。
因此,您可以通过完成源块(完成将自动沿着链接传播到subtractBlock
)并在等待subtractBlock
完成之前(异步)读取输出来修复此测试:
multiplyBlock.Complete();
int temp = subtractBlock.Receive();
await subtractBlock.Completion;