线程执行的关键是线程过程函数。一般我们会使用ThreadStart委托来调用线程过程。很多时候,线程过程也需要传入一些参数,这该如何处理?这就是本文写作的原因了。
一、ThreadStart委托的优劣测试
ThreadStart委托对应的线程过程是不能包括参数的,如:
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("Run before thread start ....");
- Thread testThread = new Thread(new ThreadStart(ThreadFunction));
- testThread.Start();
- Console.WriteLine("---------------------------------------.");
- Console.ReadLine();
- }
-
- public static void ThreadFunction()
- {
- Console.WriteLine("Thread is running ...");
- }
- }
图1是上面代码的执行效果。可以看到,虽然testThread.start()执行后才输出横线,但实际却是输出横线比线程方法先执行了。
这说明在多线程中,代码的先写并不能被先执行。而当有些情况必须先执行线程方法再执行后面的操作,该怎么办?
这就要复习Thread的Join函数了。Join方法的作用是阻塞调用线程,直到某线程终止时为止。修改下Main中的代码:
- static void Main(string[] args)
- {
- Console.WriteLine("Run before thread start ....");
- Thread testThread = new Thread(new ThreadStart(ThreadFunction));
- testThread.Start();
- testThread.Join();
- Console.WriteLine("---------------------------------------.");
- Console.ReadLine();
- }
上面的情况是最理想、最和谐的情况。而当需要给ThreadFunction()传递一个参数的时候,ThreadStart()是无能为力的。
这里.net又提供了一个ParameterizedThreadStart委托。
二、ParameterizedThreadStart委托的优劣测试
该委托的原型为:
ParameterizedThreadStart(Object obj),可以看到它的参数的一个任意类型。
案例如下:
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("Run before thread start ....");
- Thread testThread = new Thread(new ParameterizedThreadStart(ThreadFunction));
- testThread.Start("Send parameter to thread function......");
- Console.WriteLine("---------------------------------------.");
- Console.ReadLine();
- }
-
- public static void ThreadFunction(object obj)
- {
- Console.WriteLine("{0}",(string)obj);
- }
- }
从图3的运行效果,上面代码中通过在start()中传入参数,而实现了给线程过程传递参数的目的。
而这里有一个问题需要注意:由于ParameterizedThreadStart委托的参数是Object类型的,意思是可以将任意类型的数据传递到线程过程,这种方法并不是类型安全的。这又该如何处理?这就需要引入一个辅助器类来解决这个问题。
三、通过辅助器类来实现在创建线程时传递数据
通过在辅助器类中封装线程过程和一些相关数据,创建辅助器类实例时填写好数据;将辅助器类的实例线程过程赋给ThreadStart,即可以实现目的。
- // The ThreadWithState class contains the information needed for
- // a task, and the method that executes the task.
- //
- public class ThreadWithState
- {
- // State information used in the task.
- private string boilerplate;
- private int value;
- // The constructor obtains the state information.
- public ThreadWithState(string text, int number)
- {
- boilerplate = text;
- value = number;
- }
- // The thread procedure performs the task, such as formatting
- // and printing a document.
- public void ThreadProc()
- {
- Console.WriteLine(boilerplate, value);
- }
- }
-
- public class Example
- {
- public static void Main()
- {
- // Supply the state information required by the task.
- ThreadWithState tws = new ThreadWithState("This report displays the number {0}.", 42);
- // Create a thread to execute the task, and then
- // start the thread.
- Thread t = new Thread(new ThreadStart(tws.ThreadProc));
- t.Start();
- Console.WriteLine("Main thread does some work, then waits.");
- t.Join();
- Console.WriteLine("Independent task has completed; main thread ends.");
- Console.ReadLine();
- }
- }
参考文献
MSDN--启动时创建线程并传递数据