Task.Run在异步和等待中的作用

时间:2016-09-19 10:44:52

标签: c# .net multithreading asynchronous

我有一个简单的异步程序并等待:

class Program
    {
        static void Main()
        {
           var demo = new AsyncAwaitDemo();
           Task.Run(() => {demo.DoStuff()};

           while (true)
           {
               Console.WriteLine("Doing Stuff on the Main Thread...................");
           }
        }
    }

    public class AsyncAwaitDemo
    {
        public async Task DoStuff()
        {
        await LongRunningOperation();

        }

        private static async Task<string> LongRunningOperation()
        {
            int counter;

            for (counter = 0; counter < 50000; counter++)
            {
                Console.WriteLine(counter);
            }

            return "Counter = " + counter;
        }
    }

我的第一个问题是:

  1. 是否必须在任何异步等待方法中使用Task.Run,因为我刚删除并且程序变得同步。我知道这样的事实: await用于创建挂起点,并且在等待该函数的等待函数完成之前不会进一步执行。
  2. 其次,

    1. 以下代码创建了多少个线程?

      Task.Run(()=&gt; {demo.DoStuff()};

      如果它多于一个,那么是依赖于内部操作的线程数,在本例中它是带有计数器的循环。

    2. 我开始理解C#中的异步编程,阅读并练习了几个样本。我能够将上下文与我上面提到的澄清区分开来。

1 个答案:

答案 0 :(得分:3)

async / awaitTask.Run无关;但是,它们在某些情况下确实可以很好地协同工作。

Task.Run在线程池线程上运行一些代码。 async / await是一种代码转换,允许您以更自然,更强制的方式编写异步代码(有关async如何工作的详细信息,请参阅我的async intro)。

  

是否必须在任何async和await方法中使用Task.Run,​​因为我刚删除并且程序变得同步。

完全没有! async / await 非常通常在没有Task.Run的情况下使用。只要您拥有真正的异步操作,就可以使用async / await。一般来说,任何基于I / O的东西都是自然异步操作的一个很好的例子。因此,您可以仅使用HttpClient.GetStringAsync / async而不使用任何await来使用Task.Run之类的内容。

但请注意,使用async而不使用await几乎总是错误的。编译器会向LongRunningOperation发出警告,通知您它实际上并非异步。

  

以下代码创建了多少个线程? Task.Run(()=&gt; {demo.DoStuff()};

该代码只将DoStuff排队到线程池。线程池线程将执行DoStuff。线程创建取决于许多其他因素。