ContinueWith和不带ContinueWith有什么区别?

时间:2019-11-01 15:02:17

标签: c# task-parallel-library

我运行这两个版本,似乎每个版本都给我相同的输出,是连续的。

ContinueWith_Method1a();
ContinueWith_Method1b();

Task.Run(() => ContinueWith_Method1a())
        .ContinueWith(task => ContinueWith_Method1b())
        .Wait();

我尝试了以下操作,但出现此错误:

  

无法将类型'void'隐式转换为'System.Threading.Tasks.Task'

Task t = Task.Run(() => ContinueWith_Method1a())
        .ContinueWith(task => ContinueWith_Method1b())
        .Wait();

static void ContinueWith_Method1a()
{
    System.Console.WriteLine("Continue With Method 1a started.");
    Thread.Sleep(1000);// Simulate task processing time.

    System.Console.WriteLine("Continue With Method 1a completed.");
}

static void ContinueWith_Method1b()
{
    System.Console.WriteLine("Continue With Method 1b started.");
    Thread.Sleep(1000);// Simulate task processing time.

    System.Console.WriteLine("Continue With Method 1b completed.");
}

2 个答案:

答案 0 :(得分:2)

ContinueWith在第一个任务完成后启动下一个任务。 因此,您的两个示例都同步运行(首先是方法A,然后是方法b)

编辑:

除了进行编辑外,您的错误是由.Wait()函数引起的,该函数等待任务并返回void。

答案 1 :(得分:1)

  

ContinueWith和不使用ContinueWith有什么区别?

您的帖子标题问题极具误导性。在代码示例中使用ContinueWith()最少有趣的区别。更重要的区别是,第一个示例仅直接调用方法,而第二个示例使用Task.Run().

现在,因为它发生了,所以没有理由像第二个示例那样编写代码。即使忽略ContinueWith()方面,如果您所有的任务都只是调用一个方法,而您要做的所有事情都是同步等待该任务(即调用Wait()方法),那么您最好只在当前线程中调用该方法。在这种情况下,无需Task.Run()

类似地,如果您要使用ContinueWith()进行的所有操作都在之后立即调用另一个方法,那么您最好直接调用该方法。

通过在当前线程中进行阻塞,您已经失去了异步执行这两个方法的任何优势。

当然,在机械上有明显的区别。最终,您会得到相同的结果,但是实现该结果的方式却大不相同。在第一个示例中,您只是一个接一个地调用方法。每个调用都在当前线程中执行。在第二个示例中,您实质上是在要求阻止当前线程等待的同时,要求线程池按顺序执行每个方法。

这类似于您将洋葱削皮然后自己切碎,然后要求其他人将洋葱削皮然后切碎的区别,而当您坐在那里摇动拇指等待他们完成这些操作时。

最后,对于收到的错误消息,“无法将类型'void'隐式转换为'System.Threading.Tasks.Task'“ ,这仅是因为您添加了{{ 1}}变量,并尝试将其设置为Task t方法的结果。由于Wait()方法不返回任何内容(即声明的返回类型为Wait()),所以不要介意void的值,因此无法设置{{1 }}使用其返回值。因此,错误消息。如果要分配Task变量,则只需忽略对t的调用:

Task