欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解C# 线程的挂起与唤醒

程序员文章站 2022-03-10 17:44:32
如果说c#和c++有什么不同,博主不得不说,对于异步的支持程度是c#的一一个伟大的进步。 其实早期的c++都没有异步,并发的概念。博主第一次使用c++创建异步程序的时候,是使用boost库的内容进行...

     如果说c#和c++有什么不同,博主不得不说,对于异步的支持程度是c#的一一个伟大的进步。

    其实早期的c++都没有异步,并发的概念。博主第一次使用c++创建异步程序的时候,是使用boost库的内容进行实现的。相对而言,c#对于异步的支持可以说是相当的好。相信很多名词大家都很耳熟能详,比如说thread,begininvoke,delegate,backgroundworker等等。。。其实楼主在使用了这么多的异步操作过程中,还是觉得backgroudworker比较好用。

    当然,我们今天要说的和上面的无关。讲述的是如何在线程中进行挂起唤醒操作。

    假设,有一个thread现在需要挂起,等到合适的时候再唤醒那么这个线程(消费者模式)。如果大家需要用suspend,resume操作,我建议还是要思考再三。以下是msdn原话():

    do not use the suspend and resume methods to synchronize the activities of threads. you have no way of knowing what code a thread is executing when you suspend it. if you suspend a thread while it holds locks during a security permission evaluation, other threads in the appdomain might be blocked. if you suspend a thread while it is executing a class constructor, other threads in the appdomain that attempt to use that class are blocked. deadlocks can occur very easily.

     本篇文章要说的线程挂起与继续的方式其实是利用autoresetevent和manualresetevent的方法进行堵塞和继续的。

在介绍autoresetevent和manualresetevent之前,先介绍一个概念,就是线程中set()和reset()的区别。

  • set:指的是将一个事件设置为有信号,那么被这个事件堵塞的线程就会继续下去。
  • reset:指的是将一个事件设置为无信号,那么尝试继续的事件就会被堵塞。

一,autoresetevent类

     这个类的字面意思就能够解释一切:自动reset的事件,就是这个事件一旦set之后,如果某个线程堵塞被继续了,那么就会自动reset。下一次如果尝试继续,依然会被堵塞。

      其中autoresetevent类的构造函数有一个参数 是bool型。

     msdn的解释是:

      initializes a new instance of the autoresetevent class with a boolean value indicating whether to set the initial state to signaled.

    如果这个参数是true,那么第一次尝试继续就不会被阻塞。如果这个参数是false,那么第一次尝试继续就会被堵塞。

    以下是测试代码,取自msdn:

其中,autoresetevent.waitone()这个方法就是线程中尝试继续。如果没有set信号,那么就会一直阻塞,如果收到set信号该线程就会继续。但是因为是autoresetevent,所以下一次waitone依然会被阻塞。

上面代码的输出结果是:

二,manualresetevent

manualresetevent和autoresetevent大部分概念都是相同的,最大的不同就是一个是自动reset一个是手动reset。也就是说,如果使用manualresetevent类,一旦set之后,所有已经阻塞的线程(waitone())都会继续。而且之后调用waitone的线程也不会被堵塞,除非手动再次reset。也就是说,这个类是手动开启关闭信号的事件。

以下是测试代码,取自msdn:

输出结果是:

manualresetevent类的输出结果与autoresetevent输出结果最大的不同是在于:

如果不手动reset,一旦调用set方法,那么manualresetevent.waitone()就不会堵塞。

但是,autoresetevent会自动reset,所以哪怕不手动reset,每一次autoresetevent.waitone()都需要set方法进行触发以继续线程。

以上就是详解c# 线程的挂起与唤醒的详细内容,更多关于c# 线程的挂起与唤醒的资料请关注其它相关文章!

相关标签: c# 线程