【发布时间】:2015-11-04 09:27:01
【问题描述】:
我有一个使用 TPL 数据流实现由 3 个步骤组成的数据流的类。
在构造函数中,我将步骤创建为 TransformBlocks,并使用 LinkTo 将它们链接起来,并将 DataflowLinkOptions.PropagateCompletion 设置为 true。该类公开了一个方法,该方法通过在第一步调用 SendAsync 来启动工作流。该方法返回工作流最后一步的“完成”属性。
目前,工作流中的步骤似乎按预期执行,但最后一步永远不会完成,除非我明确调用 Complete。但是这样做会缩短工作流程并且没有执行任何步骤?我做错了什么?
public class MessagePipeline {
private TransformBlock<object, object> step1;
private TransformBlock<object, object> step2;
private TransformBlock<object, object> step3;
public MessagePipeline() {
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
step1 = new TransformBlock<object, object>(
x => {
Console.WriteLine("Step1...");
return x;
});
step2 = new TransformBlock<object, object>(
x => {
Console.WriteLine("Step2...");
return x;
});
step3 = new TransformBlock<object, object>(
x => {
Console.WriteLine("Step3...");
return x;
});
step1.LinkTo(step2, linkOptions);
step2.LinkTo(step3, linkOptions);
}
public Task Push(object message) {
step1.SendAsync(message);
step1.Complete();
return step3.Completion;
}
}
...
public class Program {
public static void Main(string[] args) {
var pipeline = new MessagePipeline();
var result = pipeline.Push("Hello, world!");
result.ContinueWith(_ => Console.WriteLine("Completed"));
Console.ReadLine();
}
}
【问题讨论】:
-
这是数据流,不是工作流
-
@PanagiotisKanavos:感谢您的更正;-)
-
代码似乎与问题无关。调用
Complete()的代码在哪里?您在哪里/如何等待完成?步骤是如何关联的? -
@PanagiotisKanavos:好的。我现在把代码放好了。
-
问题是
step3永远不会完成 - 它是一个 TransformBlock 并且没有人检索到它的输出消息。因此,该块永远无法完成。应该是ActionBlock
标签: c# task-parallel-library tpl-dataflow