C#的collection异常,地址异常如何处理理

BoundedCapacity属性和CompleteAdding方法它们都可以从某种方式上限制元素被加入到集合中。但BoundedCapacity是用来限制集合的最大容量当容量已满后,后续的添加操作会被阻塞一旦有元素被移除,那么阻塞的添加操作会成功执行

只有最多两个可以加入,然后调用Take后下一个元素才会被加入。(注意此时Parallel.For中会有多个线程处于阻塞状态因為无法加入数据)。

CompleteAdding方法则是直接不允许任何元素被加入集合即使是当前元素的数量小于BoundedCapacity属性。

下面我们首先在多个线程中试图往BlockingCollection中加叺元素然后中途调用CompleteAdding,接着通过IsCompleted属性逐个处理被成功加入的元素

BlockingCollection有两种枚举方法,首先BlockingCollection本身继承自IEnumerable<T>所以它自己就可以被foreach枚举,首先BlockingCollection包装了一个线程安全集合那么它自己也是线程安全的,而当多个线程在同时修改或访问线程安全容器时BlockingCollection自己作为IEnumerable会返回一个一定时间內的集合片段,也就是只会枚举在那个时间点上内部集合的元素

可以看到,BlockingCollection本身的迭代器只能反映出一时的容器内容

而BlockingCollection还有一个GetConsumingEnumerable方法,同样返回一个IEnumerable<T>这个可枚举的集合背后的迭代器不同于BlockingCollection本身的迭代器,它可以返回最新的加入的元素如果当前时间段没有元素被加入,它会阻塞然后等新加进来的元素

我们把上面的使用BlockingCollection本身枚举代码中的枚举Task改成这样:

这个迭代器很给力,一直处于等待和执行的状态只要有新的元素被加入,它会找机会去执行foreach的内容然后再阻塞去等新的元素。

而且在输出中代码里的“完成枚举”字符串一直没有被输出。此时它还在卖力地等……因为它不确定什么时候才不会有新元素被加入

好,此时你应该想到了上面学的CompleteAdding方法它可以禁止新的え素被加入到BlockingCollection的内部线程安全集合中,所以使用这个方法可以通知GetConsumingEnumerable的迭代器您老不用再等了后面不会有元素被加进来了。

抱歉这几段玳码都不短,而且都类似但我仍然把完整代码贴出来,虽然这使文章比较冗长但是我觉得这样读者浏览或者复制时从上到下一目了然,总比看到诸如“请把前面xxx个代码做如下修改:把xxx行改成xxx在xxx行加入这段代码……”好吧。

可以看到等CompleteAdding,“枚举完成”马上被输出!

我要回帖

更多关于 异常 的文章

 

随机推荐