.net中向线程过程传递参数的最优方法

    线程执行的关键是线程过程函数。一般我们会使用ThreadStart委托来调用线程过程。很多时候,线程过程也需要传入一些参数,这该如何处理?这就是本文写作的原因了。

一、ThreadStart委托的优劣测试

    ThreadStart委托对应的线程过程是不能包括参数的,如:


  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Console.WriteLine("Run before thread start ....");
  6.         Thread testThread = new Thread(new ThreadStart(ThreadFunction));
  7.         testThread.Start();
  8.         Console.WriteLine("---------------------------------------.");
  9.         Console.ReadLine();
  10.     }

  11.     public static void ThreadFunction()
  12.     {
  13.         Console.WriteLine("Thread is running ...");
  14.     }
  15. }


.net中向线程过程传递参数的最优方法
图1

    图1是上面代码的执行效果。可以看到,虽然testThread.start()执行后才输出横线,但实际却是输出横线比线程方法先执行了

    这说明在多线程中,代码的先写并不能被先执行。而当有些情况必须先执行线程方法再执行后面的操作,该怎么办?

    这就要复习Thread的Join函数了。Join方法的作用是阻塞调用线程,直到某线程终止时为止。修改下Main中的代码:


  1. static void Main(string[] args)
  2. {
  3.     Console.WriteLine("Run before thread start ....");
  4.     Thread testThread = new Thread(new ThreadStart(ThreadFunction));
  5.     testThread.Start();
  6.     testThread.Join();
  7.     Console.WriteLine("---------------------------------------.");
  8.     Console.ReadLine();
  9. }


.net中向线程过程传递参数的最优方法 图2

 

    上面的情况是最理想、最和谐的情况而当需要给ThreadFunction()传递一个参数的时候,ThreadStart()是无能为力的

    这里.net又提供了一个ParameterizedThreadStart委托。

 

二、ParameterizedThreadStart委托的优劣测试

    该委托的原型为:

    ParameterizedThreadStart(Object obj),可以看到它的参数的一个任意类型。

    案例如下:


  1. class Program
  2. {
  3.     static void Main(string[] args)
  4.     {
  5.         Console.WriteLine("Run before thread start ....");
  6.         Thread testThread = new Thread(new ParameterizedThreadStart(ThreadFunction));
  7.         testThread.Start("Send parameter to thread function......");
  8.         Console.WriteLine("---------------------------------------.");
  9.         Console.ReadLine();
  10.     }

  11.     public static void ThreadFunction(object obj)
  12.     {
  13.         Console.WriteLine("{0}",(string)obj);
  14.     }
  15. }


.net中向线程过程传递参数的最优方法
图3



    从图3的运行效果,上面代码中通过在start()中传入参数,而实现了给线程过程传递参数的目的。

    而这里有一个问题需要注意:由于ParameterizedThreadStart委托的参数是Object类型的,意思是可以将任意类型的数据传递到线程过程,这种方法并不是类型安全的。这又该如何处理?这就需要引入一个辅助器类来解决这个问题。

 

三、通过辅助器类来实现在创建线程时传递数据

    通过在辅助器类中封装线程过程和一些相关数据,创建辅助器类实例时填写好数据;将辅助器类的实例线程过程赋给ThreadStart,即可以实现目的。


  1. // The ThreadWithState class contains the information needed for
  2. // a task, and the method that executes the task.
  3. //
  4. public class ThreadWithState
  5. {
  6.     // State information used in the task.
  7.     private string boilerplate;
  8.     private int value;
  9.     // The constructor obtains the state information.
  10.     public ThreadWithState(string text, int number)
  11.     {
  12.         boilerplate = text;
  13.         value = number;
  14.     }
  15.     // The thread procedure performs the task, such as formatting
  16.     // and printing a document.
  17.     public void ThreadProc()
  18.     {
  19.         Console.WriteLine(boilerplate, value);
  20.     }
  21. }

  22. public class Example
  23. {
  24.     public static void Main()
  25.     {
  26.         // Supply the state information required by the task.
  27.         ThreadWithState tws = new ThreadWithState("This report displays the number {0}.", 42);
  28.         // Create a thread to execute the task, and then
  29.         // start the thread.
  30.         Thread t = new Thread(new ThreadStart(tws.ThreadProc));
  31.         t.Start();
  32.         Console.WriteLine("Main thread does some work, then waits.");
  33.         t.Join();
  34.         Console.WriteLine("Independent task has completed; main thread ends.");
  35.         Console.ReadLine();
  36.     }
  37. }


.net中向线程过程传递参数的最优方法 图4

 

参考文献

MSDN--启动时创建线程并传递数据

上一篇:Thread线程的深刻理解和代理方法参数[有图有真相]


下一篇:【C++11】lambda 表达式解析