在比較久以前的.NET Framework版本 大家可能直接操作過Thread
一言以蔽之 在絕大部份情況下
建議大家使用 Task 取代 Thread
再一個問題
前面我們討論過 Parallel,當然我們也可以同時 new 很多 Task,讓結果就像是 Parallel
那我該選擇哪個?
一言以蔽之 在絕大部份情況下
建議大家用 Parallel 取代 多個 Task
不說一些大道理 我們直接來看怎麼用
通常在操作 Task 上 大家最常遇到的問題就是
到底哪些操作會阻塞主執行緒 而哪些不會
粗淺的說 wait系列, await, result, getResult 要等, 其他都不用
先來看一下執行結果
想當然 實際程式發生的順序並不是1、2、3、4、5、6、7、8、9
所以我們直接來看程式碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication3
{
/// <summary>
/// 示範 Task
/// tip: 關鍵字: wait系列, await, result, getResult 要等, 其他都不用
/// </summary>
class Program
{
static void Main(string[] args)
{
//Task.Start() => 不等
Task slowTask = new Task(() => RunSlowly("【7】我是 SlowTask 我等 1 秒"));
slowTask.Start();
//Task.Factory.StartNew() => 不等
Task.Factory.StartNew(() => RunQuickly("【3】我是 QuickTask 我等 0.3 秒"));
Console.WriteLine("【1】我是主程式 我不用等 slowTask 跟 quickTask 我會最先跑");
//【Run → Result】-------------------------------------------------------------------------------
//Task.Run() => 不等
var mediumTask = Task.Run<string>(() => { return GetReturn("【4】我是 MediumTask 我等 0.6 秒"); });
Console.WriteLine("【2】並不是 Task.Run 阻塞主程式");
//Task.Result => 要等
Console.WriteLine(mediumTask.Result);
Console.WriteLine("【5】而是 MediumTask.Result 讓主程式被迫等待");
//------------------------------------------------------------------------------------------------
//【Start → Wait】-------------------------------------------------------------------------------
//Task.Start() => 不等
Task dbTask = new Task(() => GetDataFromDb("【8】花了 2 秒鐘將資料從 DB 取回"));
dbTask.Start();
Console.WriteLine("【6】並不是 Task.Start 阻塞主程式");
//Task.Wait() => 要等
dbTask.Wait();
Console.WriteLine("【9】而是 Task.Wait() 讓主程式被迫等待");
//------------------------------------------------------------------------------------------------
Console.Read();
}
static void RunQuickly(string str)
{
Thread.Sleep(300);
Console.WriteLine(str);
}
static void RunSlowly(string str)
{
Thread.Sleep(1000);
Console.WriteLine(str);
}
static string GetReturn(string str)
{
Thread.Sleep(600);
return str;
}
static void GetDataFromDb(string str)
{
Thread.Sleep(2000);
Console.WriteLine(str);
}
}
}