[C#基础]线程学习笔记(二)

[C#基础]线程学习笔记(二)

分类:C#基础

线程

参考链接:

1.前台线程与后台线程

Net的公用语言运行时(Common Language Runtime,CLR)能区分两种不同类型的线程:前台线程和后台线程。这两者的区别就是:应用程序必须运行完所有的前台线程才可以退出;而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束。一个线程是前台线程还是后台线程可由它的IsBackground属性来决定。这个属性是可读又可写的。它的默认值为false,即意味着一个线程默认为前台线程。我们可以将它的IsBackground属性设置为true,从而使之成为一个后台线程。

示例:

using System;using System.Threading;class ThreadTest11{static void Main(string[] args){for (int i = 0; i < 10; i++){Thread t = new Thread(Go);//若添加这句话,则创建完十个线程之后就会退出控制台程序//若注释这句话,则等待五秒后就会退出控制台程序//t.IsBackground = true;t.Start();}}static void Go(){DateTime start = DateTime.Now;while ((DateTime.Now – start).Seconds < 5) ;}}既然前台线程和后台线程有这种差别,那么我们怎么知道该如何设置一个线程的IsBackground属性呢?下面是一些基本的原则:对于一些在后台运行的线程,当程序结束时这些线程没有必要继续运行了,那么这些线程就应该设置为后台线程。比如一个程序启动了一个进行大量运算的线程,可是只要程序一旦结束,那个线程就失去了继续存在的意义,那么那个线程就该是作为后台线程的。而对于一些服务于用户界面的线程往往是要设置为前台线程的,因为即使程序的主线程结束了,其他的用户界面的线程很可能要继续存在来显示相关的信息,所以不能立即终止它们。这里我只是给出了一些原则,具体到实际的运用往往需要编程者的进一步仔细斟酌。

2.线程与进程

一个不错的解释:

简单地说,就是:

一个系统可以执行多个进程,允许多个任务同时运行

一个进程可以执行多个线程,允许任务分成不同的部分运行

一个进程的内存空间是共享的,每个线程都可以使用这些共享内存

3.何时使用多线程

多线程程序一般被用来在后台执行耗时的任务。主线程保持运行,并且工作线程做它的后台工作。对于Windows Forms程序来说,如果主线程试图执行冗长的操作,键盘和鼠标的操作会变的迟钝,程序也会失去响应。由于这个原因,应该在工作线程中运行一个耗时任务时添加一个工作线程,即使在主线程上有一个有好的提示“处理中…”,以防止工作无法继续。这就避免了程序出现由操作系统提示的“没有相应”,来诱使用户强制结束程序的进程而导致错误。

4.何时不使用多线程

多线程也同样会带来缺点,最大的问题是它使程序变的过于复杂,拥有多线程本身并不复杂,复杂是的线程的交互作用,这带来了无论是否交互是否是有意的,都会带来较长的开发周期,以及带来间歇性和非重复性的bugs。因此,,要么多线程的交互设计简单一些,要么就根本不使用多线程。除非你有强烈的重写和调试欲望。

当用户频繁地分配和切换线程时,多线程会带来增加资源和CPU的开销。

5.线程优先级

public enum ThreadPriority有五种取值,按优先级从高到低为:

Highest >AboveNormal >NormalBelow > Normal >Lowest

默认情况下,线程具有Normal优先级。using System;using System.Threading;class ThreadTest12{static void Main(){PriorityTest priorityTest = new PriorityTest();ThreadStart startDelegate = new ThreadStart(priorityTest.ThreadMethod);Thread threadOne = new Thread(startDelegate);threadOne.Name = "ThreadOne";Thread threadTwo = new Thread(startDelegate);threadTwo.Name = "ThreadTwo";threadTwo.Priority = ThreadPriority.BelowNormal;threadOne.Start();threadTwo.Start();// Allow counting for 3 seconds.Thread.Sleep(3000);priorityTest.LoopSwitch = false;Console.Read();}}class PriorityTest{bool loopSwitch;public PriorityTest(){loopSwitch = true;}public bool LoopSwitch{set { loopSwitch = value; }}public void ThreadMethod(){long threadCount = 0;while (loopSwitch){threadCount++;}Console.WriteLine("{0} with {1,11} priority " +"has a count = {2,13}", Thread.CurrentThread.Name,Thread.CurrentThread.Priority.ToString(),threadCount.ToString("N0"));}}运行结果:

6.异常处理

using System;using System.Threading;class ThreadTest13{static void Main(string[] args){try{new Thread(Go).Start();}catch (Exception ex){Console.WriteLine("Exception");}}static void Go(){throw null;}}这里try/catch语句一点用也没有,新创建的线程会引发NullReferenceException异常

正确的捕获异常的方法是:

using System;using System.Threading;class ThreadTest13{static void Main(string[] args){new Thread(Go).Start();}static void Go(){try{throw null;}catch (Exception ex){Console.WriteLine("Exception");Console.Read();}}}

版权声明:本文为博主原创文章,未经博主允许不得转载。

上一篇[C#基础]线程学习笔记(一)下一篇[C#基础]线程同步技术之Join方法

明天的希望,让我们忘了今天的痛苦

[C#基础]线程学习笔记(二)

相关文章:

你感兴趣的文章:

标签云: