在這裡的練習中,我們使用了方法
Task.Factory.StartNew
來建立一個工作,這個靜態方法要接受一個 Action
委派方法作為引數,這個委派方法就是要來進行非同步執行的方法。
Task.WhenAll 方法會以非同步方式來等候多個 Task 或 Task 物件完成,因此,與執行緒的開發設計不同,使用工作可以有更多的方法與技巧,可以等候部分或者全部工作完成後,才會繼續進行處理其他程式碼。
這是執行結果
Press any key for continuing...
http://www.msn.com/zh-tw/ 執行緒 ID 5
https://world.taobao.com/ 執行緒 ID 6
https://tw.yahoo.com/ 執行緒 ID 3
https://www.microsoft.com 執行緒 ID 4
https://www.microsoft.com 的內容大小為 1020 bytes
https://world.taobao.com/ 的內容大小為 220949 bytes
https://www.microsoft.com 花費時間為 268.2176 ms
https://world.taobao.com/ 花費時間為 268.6948 ms
http://www.msn.com/zh-tw/ 的內容大小為 46066 bytes
http://www.msn.com/zh-tw/ 花費時間為 273.3024 ms
https://tw.yahoo.com/ 的內容大小為 192192 bytes
https://tw.yahoo.com/ 花費時間為 447.7144 ms
抓取四個網站內容 花費時間為 509.5968 ms
Press any key for continuing...
底下是完整的測試程式碼
class Program
{
static string[] Urls = new string[]
{
"https://www.microsoft.com",
"https://tw.yahoo.com/",
"http://www.msn.com/zh-tw/",
"https://world.taobao.com/"
};
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Task t1 = Task.Factory.StartNew(() =>
{
GetWebContent(Urls[0]);
});
Task t2 = Task.Factory.StartNew(() =>
{
GetWebContent(Urls[1]);
});
Task t3 = Task.Factory.StartNew(() =>
{
GetWebContent(Urls[2]);
});
Task t4 = Task.Factory.StartNew(() =>
{
GetWebContent(Urls[3]);
});
Task.WhenAll(t1, t2, t3, t4).ContinueWith(t =>
{
sw.Stop();
Console.WriteLine($"抓取四個網站內容 花費時間為 {sw.Elapsed.TotalMilliseconds} ms");
Console.WriteLine($"Press any key for continuing...{Environment.NewLine}");
});
//// 這裡是另外一種做法
//Task.WhenAll(t1, t2, t3, t4).ContinueWith(t =>
//{
//}).Wait();
//sw.Stop();
//Console.WriteLine($"抓取四個網站內容 花費時間為 {sw.Elapsed.TotalMilliseconds} ms");
//Console.WriteLine($"Press any key for continuing...{Environment.NewLine}");
Console.WriteLine($"Press any key for continuing...{Environment.NewLine}");
Console.ReadKey();
}
private static void GetWebContent(object url)
{
Console.WriteLine($"{url} 執行緒 ID {Thread.CurrentThread.ManagedThreadId}");
Stopwatch sw = new Stopwatch();
sw.Start();
using (var client = new HttpClient())
{
string content = client.GetStringAsync(url.ToString()).Result;
Console.WriteLine($"{url} 的內容大小為 {content.Length} bytes");
}
sw.Stop();
Console.WriteLine($"{url} 花費時間為 {sw.Elapsed.TotalMilliseconds} ms");
}
}
工作式非同步模式 (TAP) 是以 System.Threading.Tasks 命名空間中的 System.Threading.Tasks.Task 和 System.Threading.Tasks.Task<TResult> 類型為基礎,這兩種類別用於表示任意非同步作業。 在新開發非同步專案時建議使用TAP模式。