在系統中單開線程進行操做,常常用到Task,發現Task主要有如下兩種方法async
Task.Factory.StartNew(() => { });
Task.Run(() => { });spa
初識不知其中區別,特地參考其餘文章已作總結https://www.mgenware.com/blog/?p=338線程
首先說明Task.UnWrap的基本使用code
這個擴展方法定義在TaskExtensions類型中,命名空間在System.Threading.Tasks。Unwrap會把嵌套的Task<Task>或者Task<Task<T>>的結果提取出來。blog
就像這樣,不用Unwrap的話:string
1 static void Main(string[] args) 2 { 3 doo(); 4 Task.Delay(-1).Wait(); 5 } 6 7 static async void doo() 8 { 9 //運行嵌套的Task 10 //Task返回Task<Task<string>> 11 //第一個await後result類型爲Task<string> 12 var result = await Task.Run<Task<string>>(() => 13 { 14 var task = Task.Run<string>(() => 15 { 16 Task.Delay(1000).Wait(); 17 return "Mgen"; 18 }); 19 return task; 20 }); 21 22 //第二個await後纔會返回string 23 Console.WriteLine(await result); 24 }
使用Unwrap後,結果能夠直接從嵌套Task中提取出來:it
1 static async void doo() 2 { 3 //運行嵌套的Task 4 //Task返回Task<Task<string>> 5 //await後類型爲Task<string>,Unwrap後result類型爲string 6 var result = await Task.Run<Task<string>>(() => 7 { 8 var task = Task.Run<string>(() => 9 { 10 Task.Delay(1000).Wait(); 11 return "Mgen"; 12 }); 13 return task; 14 }).Unwrap(); 15 16 //不須要await,result已是string 17 Console.WriteLine(result); 18 }
簡單地講,Task.Factory.StartNew和Task.Run區別之一就有Task.Run會自動執行Unwrap操做,可是Task.Factory.StartNew不會,Task.Run就是Task.Factory.StartNew的更人性化封裝,而Task.Factory.StartNew則是原始的執行。io
經過代碼來驗證:class
1 var task1 = Task.Factory.StartNew(async () => "Mgen"); 2 var task2 = Task.Run(async () => "Mgen"); 3 4 Console.WriteLine(task1.GetType()); 5 Console.WriteLine(task2.GetType());
輸出擴展
1 System.Threading.Tasks.Task`1[System.Threading.Tasks.Task`1[System.String]] 2 System.Threading.Tasks.UnwrapPromise`1[System.String]
能夠看到
使用Task.Factory.StartNew會返回原始的Task<Task<string>>。可是Task.Run則會直接返回async Lambda的結果,中間的Unwrap操做會自動進行。