新新建 Thread 对象会新建托管线程。 Thread 类包含需要使用 ThreadStart 委托或 ParameterizedThreadStart 委托的构造函数;委托包装在调用 Start 方法时由新线程调用的方法。 多次调用 Start 会导致 ThreadStateException 抛出。
通常情况下,在 Start 方法返回结果后,新线程其实紧接着启动。 可以使用 ThreadState 和 IsAlive 属性,以确定任意时刻的线程状态,但不得将这些属性用于同步线程活动。
备注 线程一旦启动,就无需保留对 Thread 对象的引用。 线程可以继续执行到线程过程结束。
下面的代码示例新建两个线程,以对另一个对象调用实例和静态方法。
关于Thread类中的属性和方法等可参考官方文档
using System; using System.Threading; public class ServerClass { // The method that will be called when the thread is started. public void InstanceMethod() { Console.WriteLine( "ServerClass.InstanceMethod is running on another thread."); // Pause for a moment to provide a delay to make // threads more apparent. Thread.Sleep(3000); Console.WriteLine( "The instance method called by the worker thread has ended."); } public static void StaticMethod() { Console.WriteLine( "ServerClass.StaticMethod is running on another thread."); // Pause for a moment to provide a delay to make // threads more apparent. Thread.Sleep(5000); Console.WriteLine( "The static method called by the worker thread has ended."); } } public class Simple { public static void Main() { ServerClass serverObject = new ServerClass(); // Create the thread object, passing in the // serverObject.InstanceMethod method using a // ThreadStart delegate. Thread InstanceCaller = new Thread( new ThreadStart(serverObject.InstanceMethod)); // Start the thread. InstanceCaller.Start(); Console.WriteLine("The Main() thread calls this after " + "starting the new InstanceCaller thread."); // Create the thread object, passing in the // serverObject.StaticMethod method using a // ThreadStart delegate. Thread StaticCaller = new Thread( new ThreadStart(ServerClass.StaticMethod)); // Start the thread. StaticCaller.Start(); Console.WriteLine("The Main() thread calls this after " + "starting the new StaticCaller thread."); } } // The example displays the output like the following: // The Main() thread calls this after starting the new InstanceCaller thread. // The Main() thread calls this after starting the new StaticCaller thread. // ServerClass.StaticMethod is running on another thread. // ServerClass.InstanceMethod is running on another thread. // The instance method called by the worker thread has ended. // The static method called by the worker thread has ended.
将数据传递到线程
调用 Thread.Start(Object) 时,使用 ParameterizedThreadStart 委托可将包含数据的对象轻松传递给线程。 有关代码示例,请参阅 ParameterizedThreadStart。
使用 ParameterizedThreadStart 委托不是传递数据的类型安全方式,因为 Thread.Start(Object) 方法接受任何对象。 替换方法是,将线程过程和数据封装到帮助程序类中,并使用 ThreadStart 委托执行线程过程。 下面的示例演示这一方法:
using System; using System.Threading; // 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 numberValue; // The constructor obtains the state information. public ThreadWithState(string text, int number) { boilerplate = text; numberValue = number; } // The thread procedure performs the task, such as formatting // and printing a document. public void ThreadProc() { Console.WriteLine(boilerplate, numberValue); } } // Entry point for the example. // 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."); } } // The example displays the following output: // Main thread does some work, then waits. // This report displays the number 42. // Independent task has completed; main thread ends.
ThreadStart 和 ParameterizedThreadStart 委托都没有返回值,因为没有从异步调用返回数据的位置。 若要检索线程方法的结果,可以使用回叫方法,如下一节所示。
使用回叫方法检索线程中的数据 下面的示例展示了从线程检索数据的回调方法。 包含数据和线程方法的类构造函数还接受表示回调方法的委托;在线程方法结束前,它调用回调委托。
使用回调方法检索线程中的数据
下面的示例展示了从线程检索数据的回调方法。 包含数据和线程方法的类构造函数还接受表示回调方法的委托;在线程方法结束前,它调用回调委托。
using System; using System.Threading; // The ThreadWithState class contains the information needed for // a task, the method that executes the task, and a delegate // to call when the task is complete. // public class ThreadWithState { // State information used in the task. private string boilerplate; private int numberValue; // Delegate used to execute the callback method when the // task is complete. private ExampleCallback callback; // The constructor obtains the state information and the // callback delegate. public ThreadWithState(string text, int number, ExampleCallback callbackDelegate) { boilerplate = text; numberValue = number; callback = callbackDelegate; } // The thread procedure performs the task, such as // formatting and printing a document, and then invokes // the callback delegate with the number of lines printed. public void ThreadProc() { Console.WriteLine(boilerplate, numberValue); if (callback != null) callback(1); } } // Delegate that defines the signature for the callback method. // public delegate void ExampleCallback(int lineCount); // Entry point for the example. // 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, new ExampleCallback(ResultCallback) ); 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."); } // The callback method must match the signature of the // callback delegate. // public static void ResultCallback(int lineCount) { Console.WriteLine( "Independent task printed {0} lines.", lineCount); } } // The example displays the following output: // Main thread does some work, then waits. // This report displays the number 42. // Independent task printed 1 lines. // Independent task has completed; main thread ends.