Task.ContinueWith在任务完成执行之前运行。

4
在控制台应用程序的Main方法中:
Do().ContinueWith(t => Do())
    .ContinueWith(t => Do())
    .ContinueWith(t => Do());

Do 是一个返回 Task 的方法:

var source = new CancellationTokenSource();
var token = source.Token;
return Task.Factory.StartNew(() =>
{
    Console.WriteLine("Inside " + _Counter);
    token.WaitHandle.WaitOne(1000);
    Console.WriteLine(_Counter++ + " is done");
}, token);

_Counter是一个整数字段:

private static int _Counter = 1;

当我运行时,结果如下:

内部1
1完成了
内部2
内部2
内部2
2完成了
3完成了
4完成了

因此,假设我有一个名为tTask和一个名为aAction<Task>
如果我调用t.ContinueWith(a),那么在t完成之后将会调用a,对吗?并且当a运行时,这应该意味着t调用的任何委托都已经结束。

是什么导致了这个结果?难道我没有明显的东西吗?
我使用的工具:

  • Windows 8 RTM
  • .NET Framework 4.5

_Counter 在哪里/如何被增加? - H H
@Henk:是打错了,我已经修复了。 - Şafak Gür
1个回答

7

如果我调用 t.ContinueWith(a),那么a会在t执行完成后被调用,对吗?

是的。但是由于你的Do函数创建了一个新的任务,它会立即完成,从而启动下一个Do。将任务创建从Do中移除(只留下Console.WriteLine内容),就可以按预期工作。

    static void Do()
    {
        Console.WriteLine("Inside " + _Counter);
        Thread.Sleep(1000);
        Console.WriteLine(_Counter + " is done");
    }

    static void Main(string[] args)
    {
        Task.Factory.StartNew(Do)
            .ContinueWith(t => Do())
            .ContinueWith(t => Do())
            .ContinueWith(t => Do());
    }

我不明白。在这里,Do().ContinueWith(t => Do()); 我调用了一次 Do()。第二个应该在第一个执行完成后(也就是一秒钟后)再被调用。 - Şafak Gür
"...由于您的Do函数创建了一个新任务,它会立即完成..." 是的,但是我调用了返回任务的.ContinueWith方法,它不会立即完成。" - Şafak Gür
1
重点是ContinueWith不期望一个Task,而是期望一个将被包装在任务中的操作。因此,如果您将Do作为ContinueWith方法的参数传递,它将创建一个调用Do的任务。也就是说,创建一个任务并立即退出。 - Kevin Gosse
我明白了,那么如果我调用 Do().ContinueWith(t => Do().Wait) 就可以了,对吗? - Şafak Gür
1
@ŞafakGür 基本上,你想做的是:Do().ContinueWith(t => Do().ContinueWith(t2 => Do().ContinueWith(t3 =>Do().ContinueWith(t4 => Do()))));(是的,这很丑陋,显然不是正确的方法) - Kevin Gosse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接