0

我学会了Taskasync/更容易使用await。现在,我正在尝试使用Task来学习async/ await

    static void Main(string[] args)
    {
        Console.ReadKey(true);
        //Magic1(); 
        Magic2();
        Console.WriteLine("{0}", DateTime.Now.ToString());
        Console.ReadKey(true);
    }

    static async void Magic1()
    {
        var taskA = GetDataAsync();
        var taskB = GetDataAsync();
        var taskC = GetDataAsync();

        Console.WriteLine("a: " + await taskA);
        Console.WriteLine("b: " + await taskB);
        Console.WriteLine("c: " + await taskC);
    }

    static Task Magic2()
    {
        return Task.Run(() =>
        {
            var taskA = GetDataAsync();
            var taskB = GetDataAsync();
            var taskC = GetDataAsync();

            Task.WaitAll(new Task[] { taskA, taskB, taskC });

            Console.WriteLine("a: " + taskA.Result);
            Console.WriteLine("b: " + taskB.Result);
            Console.WriteLine("c: " + taskC.Result);
        });
    }

    static Task<string> GetDataAsync()
    {
        return Task.Run(() => 
        {
            var startTime = DateTime.Now;
            for (var i = 0; i < 1000000000; i++)
            {
            }
            var endTime = DateTime.Now;
            return startTime.ToString() + " to " + endTime.ToString() + " is " + (endTime - startTime).ToString();
        });
    }

我创建了两种似乎做同样事情的方法,我的问题是:

1)在引擎盖下是一样的吗Magic1Magic2

2)如果它们不一样,我可以转换为不使用和关键字Magic1做同样事情的方法吗?asyncawait

4

2 回答 2

4

现在,我正在尝试利用我在 Task 中的知识来学习 async/await。

我真的建议你要这样做。虽然基于任务的并行(.NET 4.0)和基于任务的异步模式(async/ await)使用相同的类型(Task),但它们完全不同。他们解决不同的问题并有不同的工作方式。

相反,我建议你假装你对类型一无所知,Task然后从我的async介绍开始。在我的async介绍的最后是几个后续资源,包括 MSDN 文档,它们非常适合此功能。

如果你真的熟悉延续,你可以(大部分)认为await意思是“将此方法的其余部分重写为延续,并使用当前的SynchronizationContextor来安排它TaskScheduler”。但这也只是一个近似值。有很多边缘情况。这与在 a 中执行 a 完全Task.Wait[All]不同Task.Run

于 2013-11-14T18:14:38.647 回答
1

两种方法的区别:

  • 他们的代码在哪里运行。Magic2 将在线程池上而不是在调用者的同步上下文中运行,因为您(不必要地)使用了 Task.Run。如果您正在编写 UI 代码,这可能会导致 Magic2 失败。
  • 阻塞。Magic1 阻止调用者,直到调用完成。在编写异步代码时,这通常是一个错误。Magic2 不会阻止调用者,即使您删除了 Task.Run。
  • 增量工作。如果 taskB 需要更长的时间才能完成,那不会延迟 Magic2 打印 taskA 的结果。Magic1 等待所有三个任务完成,因此在 taskB 完成之前它不会打印 taskA。
于 2013-11-14T18:09:28.703 回答