1、主线程
进程创建时,默认创建一个线程,这个线程就是主线程。主线程是产生其他子线程的线程,同时,主线程必须是最后一个结束执行的线程,它完成各种关闭其他子线程的操作。尽管主线程是程序开始时自动创建的,它也可以通过Thead类对象来控制,通过调用 CurrentThread方法获得当前线程的引用
2、多线程的优缺点
优点:
----提高应用程序响应。
----使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。
----改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
缺点:
不好控制、系统运行具有不确定性
3、多线程适用的场合
4、C#之Thread
Thread: 创建并控制线程,设置其优先级并获取其状态。
常用方法:
Start() :让操作系统将当前实例的状态更改为 ThreadState.Running。该线程的状态必须为 Running时,操作系统才可以调度该线程。
一旦线程处于 ThreadState.Running 状态,操作系统就可以安排其执行。 线程从方法的第一行(由提供给线程构造函数的 ThreadStart 或 ParameterizedThreadStart 委托表示)开始执行。线程一旦终止,它就无法通过再次调用 Start 来重新启动。
为了能在启动线程时动态的为线程传递参数,可以使用ParameterizedThreadStart 委托,传递给 Start(Object) 方法的对象将传递给该委托。 ParameterizedThreadStart 委托和 Thread.Start(Object) 方法重载使得将数据传递给线程过程变得简单,但由于可以将任何对象传递给 Thread.Start(Object),因此这种方法并不是类型安全的。 将数据传递给线程过程的一个更可靠的方法是将线程过程和数据字段都放入辅助对象。一种替代方法是将线程过程和数据封装在帮助器类中,并使用 ThreadStart 委托执行线程过程。这两个委托都没有返回值,因为没有地方用于从异步调用中返回数据。 为检索线程方法的结果,可以使用回调方法。
参数传递:
将需要传递的参数放在对象中public class ThreadWithState { // State information used in the task. private string boilerplate; private int value; // The constructor obtains the state information. public ThreadWithState(string text, int number) { boilerplate = text; value = number; } // The thread procedure performs the task, such as formatting // and printing a document. public void ThreadProc() { Console.WriteLine(boilerplate, value); } } // 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."); } }
回调获取线程执行结果
回调获取线程执行结果
使用回调获取线程的执行结果public class ThreadWithState { // State information used in the task. private string boilerplate; private int value; // 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; value = 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, value); 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); } }
Thread.Sleep()
调用 Thread.Sleep 方法会导致当前线程立即阻止,阻止时间的长度等于传递给 Thread.Sleep 的毫秒数,这样,就会将其时间片中剩余的部分让与另一个线程。 一个线程不能针对另一个线程调用 Thread.Sleep。
Interrupt():中断处于 WaitSleepJoin 线程状态的线程。
Suspend和Resume(已过时):挂起和继续
在 .NET Framework 2.0 版中,Thread.Suspend 和 Thread.Resume 方法已标记为过时,并将从未来版本中移除。
Abort():方法用于永久地停止托管线程。一旦线程被中止,它将无法重新启动。
Join():阻塞调用线程,直到某个线程终止时为止。
ThreadPriority(优先级)
指定 Thread 的调度优先级。
ThreadPriority 定义一组线程优先级的所有可能值。线程优先级指定一个线程相对于另一个线程的相对优先级。
每个线程都有一个分配的优先级。在运行库内创建的线程最初被分配 Normal 优先级,而在运行库外创建的线程在进入运行库时将保留其先前的优先级。可以通过访问线程的 Priority 属性来获取和设置其优先级。
根据线程的优先级调度线程的执行。用于确定线程执行顺序的调度算法随操作系统的不同而不同。操作系统也可以在用户界面的焦点在前台和后台之间移动时动态地调整线程的优先级。
一个线程的优先级不影响该线程的状态;
5、线程的前台与后台
.Net的公用语言运行时(Common Language Runtime,CLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。
一个线程是前台线程还是后台线程可由它的IsBackground属性来决定。这个属性是可读又可写的。它的默认值为false,即意味着一个线程默认为前台线程。我们可以将它的IsBackground属性设置为true,从而使之成为一个后台线程。