2016年5月11日 星期三

C#,實作簡單的多執行緒

最近又碰到了多執行緒的需求,之前有做過,可是沒有紀錄,希望這次清楚的紀錄,下次能快速地回憶起來。




首先要引用
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<stringstringstring> 失敗方法;
        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<stringstringstring> 失敗方法, Action<Exception> 發生錯誤方法, Control control)         {             this.成功方法 = 成功方法;             this.失敗方法 = 失敗方法;             this.發生錯誤方法 = 發生錯誤方法;             this.control = control;             thread.Start();         }     }








Sample  範例下載

https://drive.google.com/open?id=0B1XxIr6Ve-glRHJtbGk4OGhvYzQ

沒有留言:

張貼留言