第一部分: 入门
介绍和概念
C#支持通过多线程并行执行代码。线程是一个独立的执行路径,能够与其他线程同时运行。C#客户端程序(控制台,WPF或Windows窗体)在CLR和操作系统自动创建的单个线程(“主”线程)中启动,并通过创建其他线程而成为多线程。这是一个简单的示例及其输出:
所有示例均假定导入了以下名称空间:
using System;
using System.Threading;
class ThreadTest { static void Main() { Thread t = new Thread (WriteY); // Kick off a new thread t.Start(); // running WriteY() // Simultaneously, do something on the main thread. for (int i = 0; i < 1000; i++) Console.Write ("x"); } static void WriteY() { for (int i = 0; i < 1000; i++) Console.Write ("y"); } }
xxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyy
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
yyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
...
主线程创建一个新线程t,在该线程上运行一种方法,该方法反复打印字符“ y”。同时,主线程重复打印字符“ x”:
一旦启动,线程的IsAlive属性将返回true,直到线程结束为止。当传递给线程构造函数的委托完成执行时,线程结束。一旦结束,线程将无法重新启动。
1 static void Main() 2 { 3 new Thread (Go).Start(); // Call Go() on a new thread 4 Go(); // Call Go() on the main thread 5 } 6 7 static void Go() 8 { 9 // Declare and use a local variable - 'cycles' 10 for (int cycles = 0; cycles < 5; cycles++) Console.Write ('?'); 11 }
??????????
在每个线程的内存堆栈上创建一个单独的cycles变量副本,因此,可以预见的是,输出为十个问号。
如果线程具有对同一对象实例的公共引用,则它们共享数据。例如:
class ThreadTest { bool done; static void Main() { ThreadTest tt = new ThreadTest(); // Create a common instance new Thread (tt.Go).Start(); tt.Go(); } // Note that Go is now an instance method void Go() { if (!done) { done = true; Console.WriteLine ("Done"); } } }
由于两个线程在同一个ThreadTest实例上调用Go(),因此它们共享done字段。这导致“完成”打印一次而不是两次:
完成
静态字段提供了另一种在线程之间共享数据的方法。这是同一示例,其作为静态字段完成了:
class ThreadTest { static bool done; // Static fields are shared between all threads static void Main() { new Thread (Go).Start(); Go(); } static void Go() { if (!done) { done = true; Console.WriteLine ("Done"); } } }