首页 > 代码库 > Net线程足迹 传递参数至线程

Net线程足迹 传递参数至线程

方法一:应用ParameterizedThreadStart这个委托来传递输入参数,这种方法适用于传递单个参数的情况。

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Windows.Forms;  
  9. using System.Threading;  
  10.   
  11. namespace BeginInvokeTest  
  12. {  
  13.     /// <summary>  
  14.     /// 给线程传递参数  
  15.     /// </summary>  
  16.     public partial class Form1 : Form  
  17.     {  
  18.         public Form1()  
  19.         {  
  20.             InitializeComponent();  
  21.         }  
  22.   
  23.         private void button1_Click(object sender, EventArgs e)  
  24.         {  
  25.             //第一种方法,应用ParameterizedThreadStart这个委托来传递输入参数  
  26.             ParameterizedThreadStart start = new ParameterizedThreadStart(ChangeText);  
  27.             Thread thread = new Thread(start);  
  28.             object obj = "HelloWorld";  
  29.             thread.Start(obj);  
  30.         }  
  31.   
  32.         public delegate void ChangeTextDelegate(object message);  
  33.   
  34.         public void ChangeText(object message)  
  35.         {  
  36.             //InvokeRequired是Control的一个属性(这个属性是可以在其他线程里访问的)  
  37.             //这个属性表明调用方是否来自非UI线程,如果是,则使用BeginInvoke来调用这个函数,否则就直接调用,省去线程封送的过程  
  38.             if (this.InvokeRequired)  
  39.             {  
  40.                 this.BeginInvoke(new ChangeTextDelegate(ChangeText), message);  
  41.             }  
  42.             else  
  43.             {  
  44.                 this.Text = message.ToString();  
  45.             }  
  46.         }  
  47.   
  48.     }  
  49. }  

ParameterizedThreadStart 委托和 Thread.Start(Object) 方法重载使得将数据传递给线程过程变得简单,但由于可以将任何对象传递给 Thread.Start(Object),因此这种方法并不是类型安全的。将数据传递给线程过程的一个更可靠的方法是将线程过程和数据字段都放入辅助对 象。因此第一种方法是不推荐的。

 

方法二:利用线程实现类,将调用参数定义成属性的方式来操作线程参数,也就是将线程执行的方法和参数都封装到一个类里面。通过实例化该类,方法就可以调用属性来实现间接的类型安全地传递参数。通过之种方法可以传递多个参数。

 

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Threading;  
  3.   
  4. // The ThreadWithState class contains the information needed for  
  5. // a task, and the method that executes the task.  
  6. //  
  7. public class ThreadWithState {  
  8.     // State information used in the task.  
  9.     private string boilerplate;  
  10.     private int value;  
  11.   
  12.     // The constructor obtains the state information.  
  13.     public ThreadWithState(string text, int number)   
  14.     {  
  15.         boilerplate = text;  
  16.         value = number;  
  17.     }  
  18.   
  19.     // The thread procedure performs the task, such as formatting   
  20.     // and printing a document.  
  21.     public void ThreadProc()   
  22.     {  
  23.         Console.WriteLine(boilerplate, value);   
  24.     }  
  25. }  
  26.   
  27. // Entry point for the example.  
  28. //  
  29. public class Example {  
  30.     public static void Main()   
  31.     {  
  32.         // Supply the state information required by the task.  
  33.         ThreadWithState tws = new ThreadWithState(  
  34.             "This report displays the number {0}.", 42);  
  35.   
  36.         // Create a thread to execute the task, and then  
  37.         // start the thread.  
  38.         Thread t = new Thread(new ThreadStart(tws.ThreadProc));  
  39.         t.Start();  
  40.         Console.WriteLine("Main thread does some work, then waits.");  
  41.         t.Join();  
  42.         Console.WriteLine(  
  43.             "Independent task has completed; main thread ends.");    
  44.     }  
  45. }  

上面示例摘自MSDN

 

方法三:利用线程池来传递参数

 

方法四:利用匿名方法来传递参数,利用了匿名方法,连上面那种独立的类都省掉了,但是如果逻辑比较复杂,用这种方法就不太好了。

 

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Windows.Forms;  
  9. using System.Threading;  
  10.   
  11. namespace BeginInvokeTest  
  12. {  
  13.     public partial class Form2 : Form  
  14.     {  
  15.         public Form2()  
  16.         {  
  17.             InitializeComponent();  
  18.         }  
  19.   
  20.         private void button1_Click(object sender, EventArgs e)  
  21.         {  
  22.             Thread thread = new Thread(new ThreadStart(delegate()  
  23.             {  
  24.                 this.BeginInvoke(new ChangeTextDelegate(ChangeText), "HelloWorld");  
  25.             }));  
  26.             thread.Start();  
  27.         }  
  28.   
  29.         public delegate void ChangeTextDelegate(string message);  
  30.         public void ChangeText(string message)  
  31.         {  
  32.             this.Text = message;  
  33.         }  
  34.     }  
  35. }  

 

此外,如果需要从线程返回数据,这时可以用回调方法,下面示例摘自MSDN。

[c-sharp] view plaincopy
    1. using System;  
    2. using System.Threading;  
    3.   
    4. // The ThreadWithState class contains the information needed for  
    5. // a task, the method that executes the task, and a delegate  
    6. // to call when the task is complete.  
    7. //  
    8. public class ThreadWithState {  
    9.     // State information used in the task.  
    10.     private string boilerplate;  
    11.     private int value;  
    12.   
    13.     // Delegate used to execute the callback method when the  
    14.     // task is complete.  
    15.     private ExampleCallback callback;  
    16.   
    17.     // The constructor obtains the state information and the  
    18.     // callback delegate.  
    19.     public ThreadWithState(string text, int number,   
    20.         ExampleCallback callbackDelegate)   
    21.     {  
    22.         boilerplate = text;  
    23.         value = number;  
    24.         callback = callbackDelegate;  
    25.     }  
    26.       
    27.     // The thread procedure performs the task, such as  
    28.     // formatting and printing a document, and then invokes  
    29.     // the callback delegate with the number of lines printed.  
    30.     public void ThreadProc()   
    31.     {  
    32.         Console.WriteLine(boilerplate, value);  
    33.         if (callback != null)  
    34.             callback(1);  
    35.     }  
    36. }  
    37.   
    38. // Delegate that defines the signature for the callback method.  
    39. //  
    40. public delegate void ExampleCallback(int lineCount);  
    41.   
    42. // Entry point for the example.  
    43. //  
    44. public class Example   
    45. {  
    46.     public static void Main()   
    47.     {  
    48.         // Supply the state information required by the task.  
    49.         ThreadWithState tws = new ThreadWithState(  
    50.             "This report displays the number {0}.",  
    51.             42,  
    52.             new ExampleCallback(ResultCallback)  
    53.         );  
    54.   
    55.         Thread t = new Thread(new ThreadStart(tws.ThreadProc));  
    56.         t.Start();  
    57.         Console.WriteLine("Main thread does some work, then waits.");  
    58.         t.Join();  
    59.         Console.WriteLine(  
    60.             "Independent task has completed; main thread ends.");   
    61.     }  
    62.   
    63.     // The callback method must match the signature of the  
    64.     // callback delegate.  
    65.     //  
    66.     public static void ResultCallback(int lineCount)   
    67.     {  
    68.         Console.WriteLine(  
    69.             "Independent task printed {0} lines.", lineCount);  
    70.     }