标签:htm 开启 时间 html mic show exception cpu ++
学历代表你的过去,能力代表你的现在,学习代表你的将来
十年河东,十年河西,莫欺少年穷
学无止境,精益求精
今儿转发一篇关于C#多线程的大作,转发自:https://www.cnblogs.com/wyt007/p/9486752.html
1.1、创建线程
static void Main(string[] args) { Thread t = new Thread(PrintNumbers); t.Start();//线程开始执行 PrintNumbers(); Console.ReadKey(); } static void PrintNumbers() { Console.WriteLine("Starting..."); for (int i = 1; i < 10; i++) { Console.WriteLine(i); } }
尝试运行上述程序,执行结果如下:
从执行的结果图中,我们发现执行的结果每次可能会不一样,究其原因,是因为进程被开启并执行的模式采用的是异步的方式!
划重点,要考:(线程/进程的执行模式是异步的)
1.2、暂停线程
class Program { static void Main(string[] args) { Thread t = new Thread(PrintNumbersWithDelay); t.Start(); PrintNumbers(); Console.ReadKey(); } static void PrintNumbers() { Console.WriteLine("Starting..."); for (int i = 1; i < 10; i++) { Console.WriteLine(i); } } static void PrintNumbersWithDelay() { Console.WriteLine("Starting..."); for (int i = 1; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(2));//暂停2S Console.WriteLine(i); } } }
执行结果图:
上图中标红处是每隔两秒钟打印出来的,根据图中的两个Starting...出现的位置,我们可以得到1.1处的结论:线程/进程是异步执行的。在后文中将不再重复!
当程序运行时,会创建一个线程,该线程会执行PrintNumbersWithDelay方法中的代码。然后会立即执行PrintNumbers方法。关键之处在于在PrintNumbersWithDelay方法中加入了Thread.Sleep方法调用。这将导致线程执行该代码时,在打印任何数字之前会等待指定的时间(本例中是2秒钟),当线程处于休眠状态时,它会占用尽可能少的CPU时间。结果我们4·会发现通常后运行的PrintNumbers方法中的代码会比独立线程中的PrintNumbersWithDelay方法中的代码先执行。
划重点,要考:Sleep()方法,用于睡眠/暂停线程。
1.3、线程等待
class Program { static void Main(string[] args) { Console.WriteLine("Starting program..."); Thread t = new Thread(PrintNumbersWithDelay); t.Start(); t.Join(); Console.WriteLine("Thread completed"); } static void PrintNumbersWithDelay() { Console.WriteLine("Starting..."); for (int i = 1; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine(i); } } }
当程序运行时,启动了一个耗时较长的线程来打印数字,打印每个数字前要等待两秒。但我们在主程序中调用了t.Join方法,该方法允许我们等待直到线程t完成。当线程t完成 "时,主程序会继续运行。借助该技术可以实现在两个线程间同步执行步骤。第一个线程会等待另一个线程完成后再继续执行。第一个线程等待时是处于阻塞状态(正如暂停线程中调用 Thread.Sleep方法一样),
执行结果图如下:
当程序运行时,启动了一个耗时较长的线程来打印数字,打印每个数字前要等待两秒。但我们在主程序中调用了t.Join方法,该方法允许我们等待直到线程t完成。当线程t完成 "时,主程序会继续运行。借助该技术可以实现在两个线程间同步执行步骤。第一个线程会等待另一个线程完成后再继续执行。第一个线程等待时是处于阻塞状态(正如暂停线程中调用 Thread.Sleep方法一样),
上述我们知道线程是异步执行的,主线程无需等待子线程的返回结果(执行完),如果我们将上述方法的 t.Join方法去掉,执行结果如下图:
主线程无需等待子线程的执行结果。
划重点,要考:Join()方法用来阻塞主进程,主进程必须等待子进程执行完成后才会往下执行!利用Join方法,可实现两个线程/进程同步执行的问题!
1.4、终止进程
class Program { static void Main(string[] args) { Console.WriteLine("Starting program..."); Thread t = new Thread(PrintNumbersWithDelay); t.Start(); Thread.Sleep(TimeSpan.FromSeconds(6)); t.Abort(); Console.WriteLine("A thread has been aborted"); } static void PrintNumbersWithDelay() { Console.WriteLine("Starting..."); for (int i = 1; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine(i); } } }
当主程序和单独的数字打印线程运行时,我们等待6秒后对线程调用了t.Abort方法。这给线程注入了ThreadAbortException方法,导致线程被终结。这非常危险,因为该异常可以在任何时刻发生并可能彻底摧毁应用程序。另外,使用该技术也不一定总能终止线程。目-标线程可以通过处理该异常并调用Thread.ResetAbort方法来拒绝被终止。因此并不推荐使用,Abort方法来关闭线程。可优先使用一些其他方法,比如提供一个CancellationToken方法来,取消线程的执行。
执行结果:
划重点,要考:Abort()方法用来终止线程的执行
1.5、监测线程状态
class Program { static void Main(string[] args) { Console.WriteLine("Starting program..."); Thread t = new Thread(PrintNumbersWithStatus); Thread t2 = new Thread(DoNothing); Console.WriteLine(t.ThreadState.ToString()); t2.Start(); t.Start(); for (int i = 1; i < 30; i++) { Console.WriteLine(t.ThreadState.ToString()); } Thread.Sleep(TimeSpan.FromSeconds(6)); t.Abort(); Console.WriteLine("A thread has been aborted"); Console.WriteLine(t.ThreadState.ToString()); Console.WriteLine(t2.ThreadState.ToString()); Console.ReadKey(); } static void DoNothing() { Thread.Sleep(TimeSpan.FromSeconds(2)); } static void PrintNumbersWithStatus() { Console.WriteLine("Starting..."); Console.WriteLine(Thread.CurrentThread.ThreadState.ToString()); for (int i = 1; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine(i); } } }
当主程序启动时定义了两个不同的线程。一个将被终止,另一个则会成功完成运行。线,.程状态位于Thread对象的ThreadState属性中。ThreadState属性是一个C#枚举对象。刚开始线程状态为ThreadState.Unstarted,然后我们启动线程,并估计在一个周期为30次迭代的,区间中,线程状态会从ThreadState.Running变为ThreadState. WaitSleepJoin。
划重点,要考:ThreadState是线程的一个属性,是一个枚举类型,不同的枚举值代表线程不同的状态!
请注意始终可以通过Thread.CurrentThread静态属性获得当前Thread对象。
如果实际情况与以上不符,请增加迭代次数。终止第一个线程后,会看到现在该线程状态为ThreadState.Aborted,程序也有可能会打印出ThreadState.AbortRequested状态。这充分说明了同步两个线程的复杂性。请记住不要在程序中使用线程终止。我在这里使用它只是为 ,了展示相应的线程状态。
最后可以看到第二个线程t2成功完成并且状态为ThreadState.Stopped。另外还有一些其,他的线程状态,但是要么已经被弃用,要么没有我们实验过的几种状态有用。
1.6、
标签:htm 开启 时间 html mic show exception cpu ++
原文地址:https://www.cnblogs.com/chenwolong/p/10577198.html