線程可以使你的項目運行得更加的流暢.
什麼是線程呢?
線程(thread)是程序執行流的最小單元, 是程序中一個單一的順序控制流程. 每個程序最少有一個線程, 那就是程序本身.
在C#中, 你可以使用 System.Threading 提供的類,接口和方法實現線程的所有操作.
想象著你走進快餐店, 大叫一聲"來碗蘭州拉面", 然後就坐在飯桌上等. 當廚師聽到你的要求時,他就開始做蘭州拉面了. 理論上講, 當你叫了以後, 廚師就已經收到了命令.
用代碼可以這樣表達:
static void Main(string[] args) { string name = "蘭州拉面"; Console.WriteLine("來碗" + name); PlaceOrder(name); Console.WriteLine("坐在飯桌上...."); Console.Read(); } static void PlaceOrder(string name) { Console.WriteLine("開始制作" + name); }運行程序, 你會發現輸出結果是:
從顯示的結果來看, 這個廚師的動作非常的快, 他一聽到命令, 馬上就開始了. 為了讓這個程序的模擬比較真實, 我們可以想象"我的動作"是一個線程, 而"廚師做拉面"是一個線程. 如果我們運用線程來實現就有點意思了:
static void PlaceOrder(string name) { Thread thread1 = new Thread(new ThreadStart(Cooking)); thread1.Start(); } static void Cooking() { Console.Write("開始制作"); }
運行程序, 你會發現輸出結果是:
這是表示雖然廚師聽到你的聲音了,但是你坐在飯桌上的動作是在他開始做拉面之前. -- 更加的合情合理, 是嗎?
我們還可以引入參數:
static void PlaceOrder(string name) { Thread thread1 = new Thread(t => Cooking(name)); thread1.Start(); } static void Cooking(string name) { Console.WriteLine("開始制作" + name); }
注意上面的參數的傳遞方法只用於.net 3.5/4
如果一個飯店有多個廚師, 並且同時有多個人點餐, 我們可以像這樣模擬實現:
static void Main(string[] args) { string name = "蘭州拉面"; int number = 5; Console.WriteLine("來" + number + "碗" + name); PlaceOrder(name, 5); Console.WriteLine("坐在飯桌上...."); Console.Read(); } static void PlaceOrder(string name, int number) { for (int i = 0; i < number; i++) { Thread thread1 = new Thread(t => Cooking(name)); thread1.Start(); } } static void Cooking(string name) { Console.WriteLine("開始制作" + name); }
運行後, 結果顯示:
嗯, 有些廚師動作還是快得像機器人, 讓我們給他們一些休息的
再次運行程序, 結果是:
線程的運作是相對獨立的, 完成不同的工作. 但是它們卻是共享進程內的資源.
做個實驗:
static void PlaceOrder(string name, int number) { int[] array = new int[] {1000,500,300,500,1}; for (int i = 0; i < number; i++) { int time = array[i]; Thread thread1 = new Thread(t => Cooking(name, i,time)); thread1.Start(); } } static void Cooking(string name, int id, int time) { Thread.Sleep(10); Console.WriteLine(id + "號開始制作" + name); }
這裡我們想給每一個廚師一個編號, 但是當把i 當中參數傳遞的時候, visual studio 會發出警告:
" Access To Modified Closure “.
這個是什麼意思呢? 運行一下程序, 輸出是:
發現在運行程序的時候, 錯誤的讀取了廚師的編號, 這就是那個警告發出的原因: 因為線程們共享的名字 i 在不停的變化中, 我們沒有辦法控制一個特定線程運行時i 的值, -- 它們是相對獨立的.
解決方案就是增加一個變量名存放值作為傳遞:
static void PlaceOrder(string name, int number) { int[] array = new int[] {1000,500,300,500,1}; for (int i = 0; i < number; i++) { int j = i; int time = array[i]; Thread thread1 = new Thread(t => Cooking(name, j,time)); thread1.Start(); } }最後我們來看看, 線程中獨立運行的實驗:
static void PlaceOrder(string name, int number) { int[] array = new int[] {1000,500,300,500,1}; for (int i = 0; i < number; i++) { int j = i; int time = array[i]; Thread thread1 = new Thread(t => Cooking(name, j,time)); thread1.Start(); } } static void Cooking(string name, int id, int time) { Thread.Sleep(10); Console.WriteLine(id + "號開始制作" + name); Thread.Sleep(time); Console.WriteLine(id + "號准備完畢,花費 每個廚師的速度是不一樣的, 他們花費的時間不同, 所以先開始的不一定先完成, 上面的代碼運行的結果是:
請仔細讀讀上面的代碼和輸出的結果, 應該大家都可以理解.
本文來自於喜樂的ASP.NET(Alex Song) 轉貼請注明出處