一,问题
最近有水友提了个问题。
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说的
接着,那我们只要看一下StartNew(Action)是怎么调用重载的就知道了。
StartNew(Action)
Task.InternalStartNew中 的 GetDefaultScheduler
五,总结
Task.Run 和 Task.Factory.StartNew 的区别在于,Task.Factory.StartNew(Action)长时间运行,线程池不会等待这个线程回收