c# Thread类

时间:2022-04-06 09:09:16

现在C#已经建议摈弃使用 Suspend, Resume 暂停/恢复线程, 也尽量少用 Abort方法中断一个线程.

建议使用线程的同步手段有:  Mutex、ManualResetEvent、AutoResetEvent, Monitor.

下面再对此进行详细描述.

Thread类的构造函数有2类:

一种是不带参数(ThreadStart 委托) --

public Thread(ThreadStart start);

另一种是带参数(ParameterizedThreadStart 委托) --

public Thread(ParameterizedThreadStart start);

ParameterizedThreadStart 委托签名:

public delegate void ParameterizedThreadStart(Object obj);

示例:

1. 不带参数:

// 定义线程方法: private static void ThreadMain() { Console.WriteLine("This is other thread main method."); } // 调用: Thread mythread = new Thread(ThreadMain); mythread.Start();

2. 带参数:

// 定义线程方法: private static void MainThreadWithParameters(object o) { Data d = (Data)o; //类型转换 Console.WriteLine("Running in a thread, received {0}", d.Message); } public struct Data { public string Message; } // 调用: var data = new Data { Message = "Info" }; Thread t2 = new Thread(MainThreadWithParameters); t2.Start(data); // 传入参数

3. 通过定义类传递参数:

// 定义存放数据和线程方法的类: public class MyThread { private string message; public MyThread(string data) { this.message = data; } public void ThreadMethod() { Console.WriteLine("Running in a thread, data: {0}", this.message); } } // 调用 var obj = new MyThread("info"); Thread myThread = new Thread(obj.ThreadMethod); //ThreadStart 委托 mythread.Start();

C#中,Thread类有一个IsBackground 的属性.MSDN上对它的解释是:获取或设置一个值,该值指示某个线程是否为后台线程。

.Net中的线程,可以分为后台线程和前台线程。后台线程与前台线程并没有本质的区别,它们之间唯一的区别就是:后台线程不会防止应用程序的进程被终止掉。就是当前台线程都结束了的时候,整个程序也就结束了,即使还有后台线程正在运行,此时,所有剩余的后台线程都会被停止且不会完成.但是,只要还有一个前台线程没有结束,那么它将阻止程序结束.应用程序进程的存亡由前台线程决定而于后台线程无关.这就是它们的区别.改变线程从前台到后台不会以任何方式改变它在CPU协调程序中的优先级和状态。因为前台后线程与程序进程的优先级无关.下面的代码示例对比了前台线程与后台线程的行为。创建一个前台线程和一个后台线程。前台线程使进程保持运行,直到它完成它的 while 循环。前台线程完成后,进程在后台线程完成它的 while 循环之前终止。

using System; using System.Threading; class Test { static void Main() { BackgroundTest shortTest = new BackgroundTest(10); Thread foregroundThread = new Thread(new ThreadStart(shortTest.RunLoop)); foregroundThread.Name = "ForegroundThread"; BackgroundTest longTest = new BackgroundTest(50); Thread backgroundThread = new Thread(new ThreadStart(longTest.RunLoop)); backgroundThread.Name = "BackgroundThread"; backgroundThread.IsBackground = true; foregroundThread.Start(); backgroundThread.Start(); } } class BackgroundTest { int maxIterations; public BackgroundTest(int maxIterations) { this.maxIterations = maxIterations; } public void RunLoop() { String threadName = Thread.CurrentThread.Name; for(int i = 0; i < maxIterations; i++) { Console.WriteLine("{0} count: {1}", threadName, i.ToString()); Thread.Sleep(250); } Console.WriteLine("{0} finished counting.", threadName); } }