C#亂彈1—多執行緒
阿新 • • 發佈:2018-11-20
1. 單執行緒
實現,按下button1,控制檯顯示1 2 3 4 ... 100
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace ThreadTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { for (int i = 0; i < 100; i++) { Console.WriteLine(i); Thread.Sleep(500); } } } }
按下button1後,控制檯能夠顯示1 2 3 4 ......100,但是在button1事件程式執行結束前, 窗體被鎖定死了。
原因:主執行緒被佔用,因此需要採用多執行緒的方法來解決。一個程式相當於一個程序,一項任務相當於一個執行緒,在一個程序內是可以有多個程序的,程序有前臺程序和後臺程序之分。
2.多執行緒
採用多執行緒就可以解決上述問題了,且button2按下控制檯也顯示1 2 3 ...100.
private void button1_Click(object sender, EventArgs e) { Thread thread = new Thread(() => //程序例項化,建構函式為無參的委託,使用Lambda表示式例項化 { for (int i = 0; i < 100; i++) { Console.WriteLine(i); Thread.Sleep(500); } }); thread.IsBackground = true; //設定後臺執行緒 thread.Start(); //啟動執行緒 } private void button2_Click(object sender, EventArgs e) { Thread thread = new Thread(() => //程序例項化,建構函式為無參的委託,使用Lambda表示式例項化 { for (int i = 0; i < 100; i++) { Console.WriteLine("----------"+i+"----------------"); Thread.Sleep(100); } }); thread.IsBackground = true; //設定後臺執行緒 thread.Start(); //啟動執行緒 }art(); //啟動執行緒 }
當button1、button2按下的時候,不在控制檯顯示,在窗體標籤處顯示,該怎麼實現。
3. 跨執行緒呼叫
按鈕事件是在Thread1這個執行緒內,而標籤控制元件是在另一個執行緒內。因此需要啟用跨執行緒呼叫。
private void button1_Click(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e) { Thread thread = new Thread(() => //程序例項化,建構函式為無參的委託,使用Lambda表示式例項化 { for (int i = 0; i < 100; i++) { //Console.WriteLine(i); if(this.lblResult1.InvokeRequired) //該控制元件是否是跨執行緒,如果是跨執行緒,該值為true,否則為false { this.lblResult1.Invoke(new Action<string>(s => { this.lblResult1.Text = s; }), i.ToString()); //Invoke第一個引數為返回值為void的委託,第二個引數是給委託對應的方法傳遞引數 } Thread.Sleep(500); } }); thread.IsBackground = true; //設定後臺執行緒 thread.Start(); //啟動執行緒 } private void button2_Click(object sender, EventArgs e) { Thread thread = new Thread(() => //程序例項化,建構函式為無參的委託,使用Lambda表示式例項化 { for (int i = 0; i < 100; i++) { //Console.WriteLine("----------"+i+"----------------"); if (this.lblResult2.InvokeRequired) //該控制元件是否是跨執行緒,如果是跨執行緒,該值為true,否則為false { this.lblResult2.Invoke(new Action<string>(s => { this.lblResult2.Text = s; }), i.ToString()); //Invoke第一個引數為返回值為void的委託,第二個引數是給委託對應的方法傳遞引數 } Thread.Sleep(100); } }); thread.IsBackground = true; //設定後臺執行緒 thread.Start(); //啟動執行緒 }