Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# task.continuewith vs c中的数据流#_C#_Task Parallel Library_Task_Tpl Dataflow_Dataflow - Fatal编程技术网

C# task.continuewith vs c中的数据流#

C# task.continuewith vs c中的数据流#,c#,task-parallel-library,task,tpl-dataflow,dataflow,C#,Task Parallel Library,Task,Tpl Dataflow,Dataflow,我已经开始学习了。我正在努力找出任务与和数据流之间的区别。以下是具有相同目标的两个示例代码。首先使用任务完成。然后继续使用和数据流。 下面是使用任务的示例。继续使用 var tk1 = Task.Run(() => { Console.WriteLine("Entered 1st Task"); Thread.Sleep(3000); return 2; }); tk1.ContinueWith((t) => { Console.WriteLine(

我已经开始学习了。我正在努力找出
任务与
和数据流之间的区别。以下是具有相同目标的两个示例代码。首先使用
任务完成。然后继续使用
和数据流。
下面是使用
任务的示例。继续使用

var tk1 = Task.Run(() =>
{
    Console.WriteLine("Entered 1st Task");
    Thread.Sleep(3000);
    return 2;
});

tk1.ContinueWith((t) =>
{
    Console.WriteLine("Entered 2nd Task");
    Thread.Sleep(2000);
    Console.WriteLine(t.Result);
});

tk1.Wait();
下面是对数据流的相同操作

var df1 = new TransformBlock<int,int>(t =>
{
    Console.WriteLine("Entered 1st DF");
    Thread.Sleep(3000);
    return 2;
});

var df2 = new ActionBlock<int>(t =>
{

    Console.WriteLine("Entered 2nd Task");
    Thread.Sleep(2000);
    Console.WriteLine(t);
});

df1.LinkTo(df2);

df1.Completion.ContinueWith(t =>
df2.Complete());

df1.Post(2);

df2.Completion.Wait();
var-df1=新转换块(t=>
{
控制台写入线(“输入第一个DF”);
睡眠(3000);
返回2;
});
var df2=新动作块(t=>
{
Console.WriteLine(“已进入第二个任务”);
《睡眠》(2000年);
控制台写入线(t);
});
df1.LinkTo(df2);
df1.Completion.ContinueWith(t=>
df2.Complete());
df1.职位(2);
df2.Completion.Wait();

Task.ContinueWith
看起来比数据流提供的冗长语法简单。谁能澄清一下两者的区别吗

数据流我用来创建一个compleax进程pipleins,在这里流可以分支、合并和循环。(此处显示的示例非常简单)

Task.ContinueWith用于一个更简单的代码中,当流程仅在一个函数列表中一个接一个地完成时。

与您的代码实际上没有区别

但是,对于数据流来说,这是错误的——转换块的用途是什么,它总是产生一个独立于输入的结果

最好做一些处理

var df1 = new TransformBlock<int,int>(input =>
    {
        Console.WriteLine("Entered 1st DF");
        Thread.Sleep(3000);
        return input+1;
    });
将全部运行通过您的数据流网格并生成输出


顺便说一句:使用
async
/
wait
而不是
任务。继续使用
可以使代码更简单、更可读。

您需要完全理解
TPL数据流
的基础知识,因为现在您正在尝试做
TPL数据流
管道本身可以轻松完成的事情:

df1.LinkTo(df2, new DataflowLinkOptions { PropagateCompletion = true });
现在,对于
df1.Completion
,您不需要使用
ContinueWith
,但是您仍然需要通知
df1
块(顺便说一下,命名很难看)到(惊喜),因为与任务相比,它不知道何时完成:

df1.Post(2);
df1.Complete();
调用此方法将拒绝发送到
df1
块的所有其他消息,并且在其缓冲区变空后,它将沿着管道传播完成,因此您只需等待它(同步或异步):

所以,基本上,区别在于任务只能运行一次,而块则是在手动完成任务之前永远运行的。请注意,您仍然可以继续执行块的任务:

df2.Completion.ContinueWith(t =>
{
    // some other logic here
});
df2.Completion.Wait();
// or
await df2.Completion;
df2.Completion.ContinueWith(t =>
{
    // some other logic here
});