c# Winform 多線程操作
阿新 • • 發佈:2018-09-15
dst oss vat event component private 過程 pre ini
主要是對一個過程需要的時間很長執行時會出現界面假死的情況
方法1:
Application.DoEvents(),這種方法當你拖動窗體時,界面不會假死。但在你拖動時代碼不再執行,也就是阻塞了,當你不再控制窗體時會繼續執行,其實這還是一個單線程
for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100000; j++) { textBox1.Text = i.ToString() + " " + j.ToString(); Application.DoEvents(); } }
方法2:多線程
2.1:取消控件跨線程檢測
2.1.1取消窗體內控件的跨線程檢查(單個控件取消也可以)
public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false;//幹掉檢測 不再檢測跨線程 }
2.1.2新建線程實現跨線程訪問
/// <summary> /// 新建線程並執行/// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { ThreadStart thStart = new ThreadStart(Pro);//threadStart委托 Thread thread = new Thread(thStart); thread.Priority= ThreadPriority.Highest; thread.IsBackground = true; //關閉窗體繼續執行 thread.Start(); } public void Pro() { for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100000; j++) { textBox1.Text = j.ToString(); } } }
2.2:主線程中操作
2.2.1 不用取消跨線程訪問
/// <summary> /// 新建線程並執行 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { ThreadStart thStart = new ThreadStart(Pro);//threadStart委托 Thread thread = new Thread(thStart); thread.Priority = ThreadPriority.Highest; thread.IsBackground = true; //關閉窗體繼續執行 thread.Start(); } public void Pro() { for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100000; j++) { if (textBox1.InvokeRequired)//不同線程訪問了 textBox1.Invoke(new Action<TextBox, string>(SetTxtValue), textBox1, j.ToString());//跨線程了 else//同線程直接賦值 textBox1.Text = j.ToString(); } } } private void SetTxtValue(TextBox txt, string value) { txt.Text = value; }
註:多個線程同時訪問一個方法時 需要鎖定
public static readonly object obj = new object(); public void Pro() { //lock(obj){}=Monitor.Enter(obj) Monitor.Exit(obj) lock (obj) { for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100000; j++) { if (textBox1.InvokeRequired)//不同線程訪問了 textBox1.Invoke(new Action<TextBox, string>(SetTxtValue), textBox1, j.ToString());//跨線程了 else//同線程直接賦值 textBox1.Text = j.ToString(); } } } }
c# Winform 多線程操作