首先要引用
using System.Threading;
主執行緒 有五個事件
呼叫封裝好的方法,裡面會自己建立子執行緒
要傳遞 callback 的function,與UI (就是 this )
UI 可以傳也可以不傳,傳了會比較精簡,不傳也是可以做的。
UI是非常重要的,要有UI才能回到主執行緒,不然就會出現跨執行緒問題
流程
1.UI 呼叫封裝好的方法(裡面會建立子執行緒)
2.子執行緒跑到一半要回來更新主執行緒的UI時
方案一: 透過 Action回來的方法,這時就可以叫用自己的UI (this.Invoke)
方案二:透過傳入的UI (主執行緒UI.Invoke ,執行UI的方法)
private void btn執行緒一開始跑迴圈_Click(object sender, EventArgs e) { 子執行緒跑迴圈 執行緒一 = new 子執行緒跑迴圈(); 執行緒一.Start(成功方法, 失敗方法, 發生錯誤方法, this); }private void 成功方法(string message) { this.Invoke(new Action(() => 回到主執行緒(message))); } private void 回到主執行緒(string message){txt執行緒一.Text = message;}
private void 失敗方法(string message, string message1, string message2){txt執行緒一.Text = message + message1 + message2;}private void 發生錯誤方法(Exception ex){txt執行緒一.Text = ex.ToString();}
這個封裝好的類別,在Start時,會收到callback方法與UI
UI透過invoke(方法,參數); 這樣就可以了
public class 子執行緒跑迴圈 { private Thread thread; private Action<string> 成功方法; private Action<string, string, string> 失敗方法; private Action<Exception> 發生錯誤方法; private Control control; public 子執行緒跑迴圈() { thread = new Thread(跑迴圈); } private void 跑迴圈() { try { for (int i = 0; i < 11; i++) { System.Threading.Thread.Sleep(1000); if (i >= 0 && i < 6) { 成功方法("Success:" + i.ToString());// control.Invoke(成功方法, "Success:" + i.ToString());
continue; } if (i > 5 && i < 8) { control.Invoke(失敗方法, "Error:" + i.ToString(), "參數2", "參數3"); continue; } //故意讓程式錯誤 Convert.ToInt32("ABCDE"); } } catch (Exception ex) { control.Invoke(發生錯誤方法, ex); } } public void Start(Action<string> 成功方法, Action<string, string, string> 失敗方法, Action<Exception> 發生錯誤方法, Control control) { this.成功方法 = 成功方法; this.失敗方法 = 失敗方法; this.發生錯誤方法 = 發生錯誤方法; this.control = control; thread.Start(); } }
Sample 範例下載
https://drive.google.com/open?id=0B1XxIr6Ve-glRHJtbGk4OGhvYzQ
沒有留言:
張貼留言