c#发展

首页 » 常识 » 问答 » C阻塞队列BlockingCollec
TUhjnbcbe - 2021/3/23 15:56:00

BlockingCollection是一个比较冷门的类,我们先看下官方对这个类的定义:

简单来说,BlockingCollection就是一个线程安全的阻塞队列,利用阻塞这个特性,我们可以实现进程内的生产者-消费者模式,比如消息转发、日志记录等。

下面我们看一个例子,其用来实现消息转发,先定义一个MessageDistributer类,代码如下:

上面的代码很简单,使用BlockingCollection定义一个消息队列,然后使用AddMessage方法向队列中添加消息。重点看一下Process方法,里面写了一个死循环,里面调用BlockingCollection的Take方法,当队列中如果没有消息时,则阻塞队列,所以并不会一直循环。等到有新消息进来时,它就会继续处理。还有一个,我们在这个类中使用单独的线程来作执行Process方法。我们再看一下调用的地方,代码如下:

这里的代码就不多解释了,就是实例化MessageDistributer类,并开启线程,然后接收客户端输入的消息,我们运行一下,看下效果。如下:

这个简单的例子就结束了,大家可以按这个思路写个日志记录的类,思路就是单独使用一个线程轮询阻塞队列。其实还可以将Action委托作为消息放到队列中,这样可以实现一个任务执行器。代码如下:

到这里就可以说结束了,不过我们可以利用ManualResetEvent来自己实现一个简单的阻塞队列,如果你有兴趣,可以接着往下看。ManualResetEvent使用信号来做线程间的通信,当队列为空时,我们一直阻塞着线程就行。简单实现一个,代码如下:

上面的代码我就不多解释了,也比较简单,主要就是为队列的时候阻塞线程(WaitOne),添加项的时候发送信号(Set)。然后用自己封装的BlockingQueue替换消息转发类中BlockingCollection,最后运行正常,我就不再演示了。

最后总结一下,BlockingCollection这个类,我们平时用的比较少,如果你有在进程内用到消息订阅或单独开线程跑任务的场景时,你可以留意一下它,当然你也可以用Timer来实现。如果今天的内容能帮到你一点点,就给个赞吧(

1
查看完整版本: C阻塞队列BlockingCollec