您好,欢迎访问一九零五行业门户网

详细介绍C#Thread点点滴滴

用c#的thread做了一个简单计时器。为了让自己45分钟后就可以休息一次,45分钟过后会响音乐提示。
开始使用的timespan相减的方式,在thread的启动函数中也就是这样写的:
public void counttime() { while (true) { timespan tsnew = new timespan(datetime.now.ticks); timespan tsin = tsnew - tsold; if (tsin.minutes >= 1) { while (true) { timespan tsnewer = new timespan(datetime.now.ticks); timespan tsiner = tsnewer - tsnew; if (tsiner.minutes >= 10) { //十分钟后线程重启 tsold = tsnew; break; } } } } }
后来发现这种方法效率太低了。当然,可以使用thread.sleep(20);这个函数降低cpu占用时间。其实中间加入thread.sleep(20);就可明显的降低cpu消耗。后来发现c#中的thread中自带有函数join(),这个函数可以使线程等待一段时间。调用方法如下
th.join(new timespan(hours, minutes, seconds));在等待的这段时间里线程处于waitsleepjoin状态。
当然也可以调用thread.sleep(millionseconds);这里提一下sleep和join的区别
当线程执行sleep时系统就退出执行队列一段时间,当睡眠结束时,系统会产生一个时钟中断,从而使线程回到执行队列中恢复线程的执行。sleep方法如果参数是0,代表这个线程应当挂起让其他等待的线程运行,这里cpu回重新分配控制权,也有可能是刚才的执行的程序。这样就会有cpu占用总是100%的情况发生。有时你界面死了,但是你还是可以移动鼠标。如果是timeout.infinite,就代表将使线程休眠,直到它被调用 thread.interrupt 的另一个线程中断或被 thread.abort 中止为止。
如果父线程先于子线程结束,那么子线程将在父线程结束的同时被迫结束。thread.join()方法使父线程等待,直到子线程结束。join方法有返回值,当值为true,代表线程终止。false的话代表线程在等待了那段时间后还未终止。如果在线程unstarted状态时,调用join()就会有threadstateexception异常。如果线程已经终止,那么调用这个函数,会立即得到返回值。
例如下面的主程序
... threadstart st = new threadstart(fun); thread th = new thread(threadstart st); th.start(); application.exit(); ... //下面是fun函数 void fun() { while(true) { ... } }
这段程序的唯一毛病就是有可能在主程序退出后,从线程还没有结束。(这个从线程真可怜...)
这里顺便再提一下线程的几个状态:
创建:当创建一个新进程时,也为该进程创建了一个线程。线程还可以创建新线程。
就绪:线程已获得除处理机外的所有资源。
运行:线程正在处理机上执行。
阻塞:线程因等待某事件而暂停运行。
终止:一个线程已完成。
但是c#的线程中多了几个状态:
aborted,abortrequested,background,running,stopped,stoprequested,suspended,suspendrequested,unstarted,waitsleepjoin。
  abort()将导致threadstate.abortrequested调用abort()的线程获得控制权之后导致threadstate.aborted,abortrequested与aborted的区别在于一个停止一个未停止。而stopped则是线程终止。但是我反复试验多次发现当调用abort()函数后,线程状态会变为stopped。如何变为aborted状态,还在研究中。其他几个状态差不多。都是调用相应的函数会产生相应的状态请求,还有过一段时间才能到底相应的状态。至于unstarted是还未调用start()函数,running是调用start()或者resume()函数的结果。waitsleepjoin是在等待i/o,或者是调用join()方法。这里join()和sleep()方法的不同还在于调用join()线程状态进入waitsleepjoin,调用sleep()线程状态还是running。
挂起线程的方法是suspend();调用这个方法后,线程处于suspendrequest状态。suspended()调用后如果线程仍然在执行join()方法,因为suspended()要让线程到达安全点之后它才可以将该线程挂起,此时那线程状态就是suspendrequested|waitsleepjoin。但是这里的join里的时钟依然在计数。所以现在还不知道用什么方法来暂停这个join计数,当然也可以不使用join解决彻底暂停线程这个问题。现在不明白哪个suspended()函数是干什么的,因为线程依旧在运行中。另外值得一提的是现在不提倡使用suspend()和让线程调用suspend()后再次恢复的resume()方法。原因很简单,因为这两个方法是由另外的线程执行,另外的线程并不能准确的知道被suspend()的线程处于何种状态,如某个类的构造函数执行时期,或者析构等。所以用这个函数来同步很危险。
另外,要注意的是thread.sleep(n)这个n不能精确的控制时间。如果你认为要线程要隔多长时间,这个控制就有问题。如果当前的线程是一个前台线程,那么thread.sleep(n)就要在大于n的时间才能退出。如果是后台进程,当主程序退出后,这线程就再也不能唤醒..悲惨..所以一般也建议不用thread.sleep()函数。另外sleep函数也不能用于同步.peter说程序的sleep函数代表了一个很烂的设计。
以上就是详细介绍c#thread点点滴滴的详细内容。
其它类似信息

推荐信息