ContinueWith和任务的Result

37

我使用这段代码

    public static void Main()
    {
        Task<int> t = new Task<int>(() => { return 43; });
        t.Start();
        t.ContinueWith((i) => {return i.Result * 2; });

        Console.WriteLine("i = {0}", t.Result.ToString());

        Console.Read();
    }

我注意到 t.Result 的值为 43 而不是 86。 如果我在 ContinueWith 中打印一些内容,它会出现在控制台中。 为什么 Result 没有被 ContinueWith 修改?

3个回答

48
这是因为ContinueWith创建了一个全新的任务,你忽略了它的结果,而是打印了正确的43任务的结果。请尝试以下代码片段:
Task<int> t = new Task<int>(() => { return 43; });
t.Start();
var t2 = t.ContinueWith((i) => {return i.Result * 2; });

Console.WriteLine("i = {0}", t2.Result.ToString());

15

其他两个答案是正确的。通过ContinueWith还会返回另一个Task。如果您不关心每个单独的步骤...那么您的代码可以通过在链接它们之后分配ContinueWith的值而变得更小:

var t = Task.Run(() => 43)
        .ContinueWith(i => i.Result * 2);

// t.Result = 86

您会发现很多基于任务的代码都遵循这个规则。当你在链式使用 ContinueWith 时,通常不需要创建和启动单独的 Task 实例。


14

当第一个任务完成执行时,ContinueWith将创建一个新的任务,这个新任务可能使用相同的线程,也可能不使用,这取决于任务调度程序。

您可以使用ContinueWith<TResult>(Func<Task, TResult>)来获取第二个任务的结果。

你的代码会像这样:

 static void Main(string[] args)
        {

            Task<int> t = new Task<int>(() => { return 43; });
            t.Start();
            Task<int> t2 = t.ContinueWith<int>((i) => { return i.Result * 2; });

            Console.WriteLine("i = {0}", t2.Result.ToString());

            Console.Read();

        }

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