1. 程式人生 > >15.3 Task Task.Yield和Task.Delay說明

15.3 Task Task.Yield和Task.Delay說明

https://blog.csdn.net/hurrycxd/article/details/79827958

書上看到一個Task.Yield例子,Task.Yield方法建立一個立即返回的awaitable。等待一個Yield可以讓非同步方法在執行後續的部分時返回到呼叫方法。可以理解為離開當前的訊息佇列,回到佇列末尾,讓處理器有時間處理其他任務。
Yield方法在GUI程式設計中非常的有用,可以中斷大量的工作,讓其他任務使用處理器。看下面的程式碼:

 1         static void Main(string[] args)
 2         {
 3             Task<int
> value = FindSeriesSum(100000); 4 Console.WriteLine("主線其他任務開始"); 5 CountBig(10000); 6 CountBig(10001); 7 CountBig(10002); 8 Thread.Sleep(1000); 9 CountBig(10003); 10 Console.WriteLine("Length =" + value.Result); 11 Console.ReadKey();
12 } 13 public static async Task<int> FindSeriesSum(int i1) 14 { 15 int sum = 0; 16 for (int i = 0; i < i1; i++) 17 { 18 sum += i1; 19 if (i % 20000 == 0) 20 { 21 await
Task.Yield(); 22 Console.WriteLine("i % 20000 :i=" + i); 23 } 24 } 25 WebClient wc = new WebClient(); 26 Console.WriteLine("開始下載任務"); 27 string str = await wc.DownloadStringTaskAsync("https://www.baidu.com"); 28 return str.Length; 29 } 30 private static void CountBig(int p) 31 { 32 for (int i = 0; i < p; i++) 33 { 34 if (i == p - 1) 35 Console.WriteLine("p =" + p); 36 } 37 }

在執行下載任務await wc.DownloadStringTaskAsync("https://github.com/")前進行了大量的CPU運算,那麼執行緒會等到第一個await的時候才會非同步執行CountBig(10000);

程式執行的結果如下:

i % 20000 :i=0
i % 20000 :i=20000
i % 20000 :i=40000
i % 20000 :i=60000
i % 20000 :i=80000
開始下載任務
主線其他任務開始
p =10000
p =10001
p =10002
p =10003
Length =52728
我們需要立即返回的awaitable,讓程式執行其他的任務,去掉//await Task.Yield();前面的註釋符,得到的結果如下:

i % 20000 :i=0
主線其他任務開始
p =10000
i % 20000 :i=20000
p =10001
p =10002
i % 20000 :i=40000
i % 20000 :i=60000
i % 20000 :i=80000
開始下載任務
p =10003
Length =52728
可以看到現在開始下載任務之前就可以執行其他的任務了。最大條件的利用了資源。

Task.Delay方法建立一個Task物件,該物件暫停其線上程中的處理。

與Thread.Sleep()阻塞執行緒不同的是,Task.Delay不會阻塞執行緒,執行緒可以繼續處理其它的工作。

 1         static void Main(string[] args)
 2         {
 3             Task<int> value = FindSeriesSum(100000);
 4             Console.WriteLine("主線其他任務開始");
 5             CountBig(10000);
 6             CountBig(10001);
 7             CountBig(10002);
 8             Thread.Sleep(1000);
 9             CountBig(10003);
10             Console.WriteLine("Length =" + value.Result);
11             Console.ReadKey();
12         }
13         public static async Task<int> FindSeriesSum(int i1)
14         {
15             await Task.Delay(1000);
16             WebClient wc = new WebClient();
17             Console.WriteLine("開始下載任務");
18             string str = await wc.DownloadStringTaskAsync("https://www.baidu.com");
19             return str.Length;
20         }
21         private static void CountBig(int p)
22         {
23             for (int i = 0; i < p; i++)
24             {
25                 if (i == p - 1)
26                     Console.WriteLine("p =" + p);
27             }
28         }

主線其他任務開始
p =10000
p =10001
p =10002
開始下載任務
p =10003
Length =52728