我們在寫Remoting程序或者其他的一些應用程序的時候難免要和線程打交道,.Net使我們很容易就可以創建一個線程,但是它提供的創建線程和啟動線程的方法沒有明顯的提供參數,假如我們要用線程來啟動類裡面一個帶參數的方法該怎麼辦?下面就簡單的介紹如何使用.NET提供的豐富的框架來實現這個功能。為了可以生動詳細的介紹整個過程,我建立下面的一個.Net類,它也是要用線程啟動的方法的載體。類如下所示:
using System;
namespace WindowsApplication1
{
/// <summary>
/// Summary description for UrlFetcher.
/// </summary>
public class MyClass{
// for method 1
private string _parameter;
public MyClass(string parameter){
this._parameter = parameter;
}
public void MyMethod1(){
if(this._parameter!=null){
// do something
Console.Write(this._parameter);
}
}
// for method 2
public MyClass(){}
// this method is private,But it can be public or other
private void MyMethod2(string parameter){
// do something
Console.Write(parameter);
}
// Because delegate WaitCallback's parameter Type is object
// I will convert it to string.
public void MyMethod2(object parameter){
this.MyMethod2((string)parameter);
}
// for method 3
public string MyMethod3(string parameter){
return "參數值為:"+parameter;
}
// for mutil-parameters passed
public string MyMutilParameters(string param1,string param2){
return "參數1和參數2連接結果為:"+param1+param2;
}
}
}
嘿嘿,我的英語不行,注釋寫的不好請見諒(因為使用的是英文的),希望沒有影響您的閱讀。我想我有必要簡單的說一下上面這個類裡裡面的所包含的內容。首先包含兩個構造函數,一個帶參數一個不帶(這裡可是有意安排的)。通過類中其他方法的名字我想您一定猜出來我將介紹3種方法來傳遞參數,接下來我將逐一介紹。首先我們看看如何啟動一個線程,首先我們可以用一個函數來實例化ThreadStart委托的一個實例,然後在使用這個實例作為參數new線程(Thread)對象,最後將這個線程Start就可以了,想了解更多請參考MSDN文檔的Thread部分。
為了測試我們的結果我建立了一個WinForm的工程,其中有一個Form和4個按鈕,如果你需要所有的源碼請發送郵件到[email protected],如果我有時間我會給你發過去的。接下來是每種方法的詳細描述。
1、使用構造函數來傳遞參數
眾所周知,我們可以使用一個帶參數的構造函數來構造對象,既然這樣我們可以利用構造函數先將要使用的參數值傳遞到對象裡面的內部變量上,然後再使用一個無參數的方法來使用這個參數(假裝參數)。簡單的說就是,在類裡面聲明一個變量專門用來保存函數需要的參數,函數變成無參的形式。這種方法的最大問題就是破壞了封裝性,雖然我們不能直接方法這些變量但是隱患總是存在的(或者說看上去不爽都可以)。下面代碼片斷給出了如何使用這個方法來傳遞參數的詳細內容,這也是上面提到的4個按鈕中的一個按鈕(Button1)的Click代碼。為了有參數可傳我在WinForm全局定義了一個如下的變量:
// This is parameter's value
private string myParameter = "ParameterValue\n";
按鈕事件如下所示:
// passed parameters to thread by construct
private void button1_Click(object sender, System.EventArgs e) {
MyClass instance = new MyClass(myParameter);
new Thread (new ThreadStart(instance.MyMethod1)).Start();
}