C# Task.Run 和 Task.Factory.StartNew 区别

一,问题

最近有水友提了个问题。

Task task = Task.Factory.StartNew(async () =>
     {
      while (true)
      {
           await Task.Delay( 1000);
      }
    }
 
  Task.WaitAll(new Task[] { task });
 
结果运行到await Task.Delay( 1000);直接跳出了while,导致 Task.WaitAll完成了,这是怎么回事,
 await Task.Delay( 1000);  改成Thread.Sleep(1000)就正常了

二,解答

sp1234回答了,

果真,听君一席话,胜读十年书!

三,测试

static void Main(string[] args)
        {
            test();
            Console.WriteLine("按任意键结束........");
            Console.ReadKey();
        }
 
        private static async void test()
        {
            var task = Task.Run(async () =>
            {
                while (true)
                {
                    await Task.Delay(1000);
                    Console.Write(".");
                }
            });
            await Task.WhenAll(task);
            Console.WriteLine("完成");
        }
 
        private static async void test1()
        {
            var task = Task.Factory.StartNew(async () =>
            {
                while (true)
                {
                    await Task.Delay(1000);
                    Console.Write(".");
                }
            });
            await Task.WhenAll(task);
            Console.WriteLine("完成");
        }

Task.Run

Task.StartNew

四,探究

MSDN其实也有提到,但藏在文档里很容易被忽略。

我们先看一下:msdn说的

①,我们先把内部委托的async 去掉。

看一下返回类型。

Task.Run

Task.Factory.StartNew

②,我们在看看async action()

Task.Run

Task.Factory.StartNew

五,总结

1,调用Unwrap()方法,Task.Factory.StartNew(async action()).Unwrap() 可以实现和Task.Run(async action())  一样的功能。

2,推荐大家看一下这篇博客,很详细:https://www.cnblogs.com/qinjin/p/Task-Run-Vs-Task-Factory-StartNew.html

原文地址:https://www.cnblogs.com/hanjun0612/p/14654791.html