我刚开始阅读TPL Dataflow,对此感到困惑。虽然我已经阅读了很多与此相关的文章,但我仍然无法轻松理解。也许这很难,也许我还没有开始掌握这个想法。
我开始研究这个问题的原因是,我想实现一个可以按顺序运行并行任务的场景,并发现TPL Dataflow可以用于此目的。
我同时练习TPL和TPL Dataflow,并处于初学者水平,因此需要专家帮助指导正确方向。在我的测试方法中,我已经完成了以下事情:
现在,该过程是并行的和异步的(不会冻结我的用户界面),但生成的输出顺序不正确,而我已经读到TPL Dataflow默认保持元素的顺序。所以我的猜测是,我创建的任务是罪魁祸首,它没有按正确的顺序输出字符串。我对吗?
如果是这种情况,那么我怎样才能使这个过程既异步又有序?
我尝试将代码分离并将代码分配到不同的方法中,但我的尝试失败了,因为只有字符串被输出到文本框,什么也没有发生。
我开始研究这个问题的原因是,我想实现一个可以按顺序运行并行任务的场景,并发现TPL Dataflow可以用于此目的。
我同时练习TPL和TPL Dataflow,并处于初学者水平,因此需要专家帮助指导正确方向。在我的测试方法中,我已经完成了以下事情:
private void btnTPLDataFlow_Click(object sender, EventArgs e)
{
Stopwatch watch = new Stopwatch();
watch.Start();
txtOutput.Clear();
ExecutionDataflowBlockOptions execOptions = new ExecutionDataflowBlockOptions();
execOptions.MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded;
ActionBlock<string> actionBlock = new ActionBlock<string>(async v =>
{
await Task.Delay(200);
await Task.Factory.StartNew(
() => txtOutput.Text += v + Environment.NewLine,
CancellationToken.None,
TaskCreationOptions.None,
scheduler
);
}, execOptions);
for (int i = 1; i < 101; i++)
{
actionBlock.Post(i.ToString());
}
actionBlock.Complete();
watch.Stop();
lblTPLDataFlow.Text = Convert.ToString(watch.ElapsedMilliseconds / 1000);
}
现在,该过程是并行的和异步的(不会冻结我的用户界面),但生成的输出顺序不正确,而我已经读到TPL Dataflow默认保持元素的顺序。所以我的猜测是,我创建的任务是罪魁祸首,它没有按正确的顺序输出字符串。我对吗?
如果是这种情况,那么我怎样才能使这个过程既异步又有序?
我尝试将代码分离并将代码分配到不同的方法中,但我的尝试失败了,因为只有字符串被输出到文本框,什么也没有发生。
private async void btnTPLDataFlow_Click(object sender, EventArgs e)
{
Stopwatch watch = new Stopwatch();
watch.Start();
await TPLDataFlowOperation();
watch.Stop();
lblTPLDataFlow.Text = Convert.ToString(watch.ElapsedMilliseconds / 1000);
}
public async Task TPLDataFlowOperation()
{
var actionBlock = new ActionBlock<int>(async values => txtOutput.Text += await ProcessValues(values) + Environment.NewLine,
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded, TaskScheduler = scheduler });
for (int i = 1; i < 101; i++)
{
actionBlock.Post(i);
}
actionBlock.Complete();
await actionBlock.Completion;
}
private async Task<string> ProcessValues(int i)
{
await Task.Delay(200);
return "Test " + i;
}
我知道我写的代码不好,但这是我第一次尝试TPL Dataflow。