在線程編程中,我們都知道一般給線程傳遞參數的大致有三種方式:
1.方式一:使用ParameterizedThreadStart委托
如果使用了ParameterizedThreadStart委托,線程的入口必須有一個object類型的參數,且返回類型為void.

using System; using System.Threading; namespace ThreadWithParameters { class Program { static void Main(string[] args) { string hello = "hello world"; //這里也可簡寫成Thread thread = new Thread(ThreadMainWithParameters); //但是為了讓大家知道這里用的是ParameterizedThreadStart委托,就沒有簡寫了 Thread thread = new Thread(new ParameterizedThreadStart(ThreadMainWithParameters)); thread.Start(hello); Console.Read(); } static void ThreadMainWithParameters(object obj) { string str = obj as string; if(!string.IsNullOrEmpty(str)) Console.WriteLine("Running in a thread,received: {0}", str); } } }
以上代碼只能傳遞一個參數,如果有時我們向線程傳遞給多的參數,那種方式使用將有局限性(如果用類作為對象傳遞參數,那么需要要另外建立一個類,也稍有點麻煩)
如果用這種方法我們密切要注意的就是ThreadMainWithParameters方法里的參數必須是object類型的,我們需要進行類型轉換。此方法不作推薦。
2.方式二: 創建自定義類
定義一個類,在其中定義需要的字段,將線程的主方法定義為類的一個實例方法,請看實際的例子。

using System; using System.Threading; namespace ThreadWithParameters { public class MyThread { private string data; public MyThread(string data) { this.data = data; } public void ThreadMain() { Console.WriteLine("Running in a thread,data: {0}", data); } } class Program { static void Main(string[] args) { MyThread myThread = new MyThread("hello world"); Thread thread = new Thread(myThread.ThreadMain); thread.Start(); Console.Read(); } } }
這種方法也稍有繁瑣,也不是我重點想要探討的,如果需要,自己也可以使用。
3. 方式三:采用lambda表達式
對於lambda表達式不熟悉的可以查看微軟MSDN上的說明文檔。此處假設你熟悉。因為在大多數使用委托的時候我們一般也可以用lambda表達式的。

using System; using System.Threading; namespace ThreadWithParameters { class Program { static void Main(string[] args) { string hello = "hello world"; //如果寫成Thread thread = new Thread(ThreadMainWithParameters(hello));這種形式,編譯時就會報錯 Thread thread = new Thread(() => ThreadMainWithParameters(hello)); thread.Start(); Console.Read(); } static void ThreadMainWithParameters(string str) { Console.WriteLine("Running in a thread,received: {0}", str); } } }
此方法三可以作為推薦方法,代碼簡便,方便我們使用。上面方式三說到lambda表達式,既然lambda表達式可以使用,那么我們也可以使用delegate委托。下面主要探討的是使用這種方法。
4. 方式三:使用delegate委托
Multhd = new Thread[ThreadCount]; thread_Separate_baseCount = C_num / ThreadCount;//每個線程的終端數 listViewEx2.Items.Clear(); for (int j = 0; j < ThreadCount; j++) { if (j == ThreadCount - 1)//最后一個線程 { Multhd[j] = new Thread(delegate() { Run2( j * thread_Separate_baseCount, C_num - 1); }); } else//其它線程 { Multhd[j] = new Thread(delegate() { Run2( j * thread_Separate_baseCount, (j + 1) * thread_Separate_baseCount - 1); }); } }
上面代碼Run(arg1,arg2.....,argn)是我們自定義的方法,在這個方法中我們可以設置任意多個參數,看也算是簡單的吧。
以上代碼完全可以運行,也不會出現bug什么之類的,但是實際運行情況卻令我驚訝不已,用for循環創建一個線程時,關閉重開線程不會有任何問題。因為只是一個線程,可能沒有什么事。但是至二個或者二個以上時,關閉再重開線程(我需要不斷關閉打開終端),程序不會報錯,調試器也沒有什么問題,電腦有時會毫無預兆的關機,在我們做事時毫無預兆的關機這可是一個致命的問題啊,沒有誰願意這樣的。以為是偶然,重復了多次結果都一樣,偶然也必然存在這種必然。
為什么一個線程時沒事,多個線程時運行時是不是上面的線程都指向了同一個delegate委托的地址,才導致這樣會毫無預兆的關機?這些等待我們去驗證,在此熱烈歡迎有經驗的朋友和我一塊探討。