2012/5/11
C#執行緒的使用方式其實跟委派脫離不了關係
需要將要執行的工作交給委派
再透過執行續執行委派的方法
簡易使用執行緒(Thread)步驟:
Step 1. 使用多執行緒時先匯入System.Threading
using System.Threading;
Step 2. 欲在執行緒上的工作(需委派的方法)
void SayHello()
{
Console.WriteLine("Hello,Thread{0}", Thread.CurrentThread.ManagedThreadId);
}
//Thread.CurrentThread.ManagedThreadId 目前執行緒的名稱
Step 3. 建立ThreadStart委派,它是用來表示在執行緒上執行的方法(已經是系統寫好的Delagte)
//public delegate void ThreadStart ()
ThreadStart ts = new ThreadStart(SayHello); //委派方法
*既然ThreadStart這個委派無參數值
可不可以自己自訂一個委派去執行呢? Ans:不可以,稍後解釋原因
Step 4. 建立Thread並將所要執行的委派當作參數
Thread tt = new Thread(ts);
*為何不可以自訂一個delagate當作Thread的參數?
Ans:因為Thread的多載清單上
只允許 ParameterizedThreadStart 與 ThreadStart
Step 5. 啟動執行緒
tt.Start();
到這邊之後,你可能會發現,你沒辦法給定參數到執行緒內部
但是這是有方法的,而且剛剛已經有提到過
這時需要使用到 ParameterizedThreadStart
這個已經定義好的委派
publicdelegatevoid ParameterizedThreadStart(Object obj)
接著我們來看看要如何去使用它
Step 1. 使用多執行緒時先匯入System.Threading
using System.Threading;
Step 2. 欲在執行緒上的工作
(需委派的方法,記得要有參數類型必須為Object)
static void SayBye(object str)
{
Console.WriteLine("{0} Bye,Thread{1}",str, Thread.CurrentThread.ManagedThreadId);
}
Step 3. 建立ParameterizedThreadStart委派並委派方法
//ParameterizedThreadStart與ThreadStart相同,只是多了參數傳遞機制。
ParameterizedThreadStart pts = new ParameterizedThreadStart(SayBye);
Step 4. 建立Thread並將所要執行的委派當作參數
Thread tt2 = new Thread(pts);
Step 5. 啟動執行緒並傳入參數
tt2.Start("Master");
輸出結果:
執行緒上操作UI
在C# form操作執行緒時
特別注意的是只有在UI執行續上操作(建立控制項之執行緒)
才能對form上面的component做改變
要怎麼知道哪個是才是UI執行續呢?
當然我也不會知道
以下範例測試出錯狀況
下為範例form圖
當按下按鈕後會於textbox新增所使用執行緒名稱
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading; //使用執行緒別忘了補上
namespace Form上UI的執行緒
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadStart ts = new ThreadStart(add_listbox);
Thread t = new Thread(ts);
t.Start();
}
//宣告一個委派(用於在控制視窗上執行的委派)
delegate void callbyUI();
void add_listbox()
{
textBox1.Text += "Thread" + Thread.CurrentThread.ManagedThreadId + Environment.NewLine;
}
}
}
紅字底線處出現錯誤
如前文所說
此處的執行緒非UI執行緒導致錯誤
如何才能防止這樣問題產生?
其實方法很簡單,只要判斷是否於UI執行緒上執行
如果不是則讓UI執行緒執行即可!
作法如下
將欲在執行緒執行的方法加入判斷
//宣告一個委派(用於在控制視窗上執行的委派)
delegate void callbyUI();
void add_listbox()
{
//public bool InvokeRequired { get; }
//取得一個值。表示是否呼叫端是在建立控制項之執行緒(UI執行緒)以外的執行緒
//因此在進行控制項的方法呼叫時,應呼叫叫用 (Invoke) 方法。
if (this.InvokeRequired)
{
//建立一個在控制視窗上執行的委派
callbyUI cb = new callbyUI(add_listbox);
//在擁有控制項基礎視窗控制代碼的執行緒上執行委派。
this.Invoke(cb);
}
else //已經在UI執行緒
{
textBox1.Text += "Thread" + Thread.CurrentThread.ManagedThreadId + Environment.NewLine;
}
其他執行緒文章
留言列表