线程执行的关键是线程过程函数。一般我们会使用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--启动时创建线程并传递数据