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");


輸出結果:

Thread1  


 

 


執行緒上操作UI

在C# form操作執行緒時

特別注意的是只有在UI執行續上操作(建立控制項之執行緒)

才能對form上面的component做改變

要怎麼知道哪個是才是UI執行續呢?

當然我也不會知道

以下範例測試出錯狀況

 下為範例form圖

Thread2_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執行緒導致錯誤

Thread2_err  

如何才能防止這樣問題產生?

其實方法很簡單,只要判斷是否於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;

}


Thread2  


其他執行緒文章

.NET 隨筆  執行緒 (Thread)(一)


arrow
arrow
    全站熱搜

    chuangmaster 發表在 痞客邦 留言(0) 人氣()