.NET(C#):线程安全集合的阻塞BlockingCollection的使用(3)

来源:未知 责任编辑:责任编辑 发表时间:2014-03-23 22:28 点击:

    Parallel.For(1, 11, forOpt, i =>
    {
        bcollec.Add(i);
        Console.WriteLine("成功加入:" + i);
        Thread.Sleep(500);
    });
});
 
Thread.Sleep(700);
//开始枚举www.2cto.com
Task.Run(() =>
{
    foreach (var i in bcollec)
        Console.WriteLine("输出:" + i);
});
 
Thread.Sleep(Timeout.Infinite);
 
我们边加入元素边进行枚举(直接在BlockingCollection上foreach),可能的输出:
成功加入:1
成功加入:6
成功加入:2
成功加入:7
输出:1
输出:6
输出:2
输出:7
成功加入:8
成功加入:3
成功加入:4
成功加入:9
成功加入:5
成功加入:10
 
可以看到,BlockingCollection本身的迭代器只能反映出一时的容器内容。
 
而BlockingCollection还有一个GetConsumingEnumerable方法,同样返回一个IEnumerable<T>,这个可枚举的集合背后的迭代器不同于BlockingCollection本身的迭代器,它可以返回最新的加入的元素,如果当前时间段没有元素被加入,它会阻塞然后等新加进来的元素。
 
我们把上面的使用BlockingCollection本身枚举代码中的枚举Task改成这样:
//开始枚举
Task.Run(() =>
{
    foreach (var i in bcollec.GetConsumingEnumerable())
        Console.WriteLine("输出:" + i);
    Console.WriteLine("完成枚举");
});
 
可能的输出:
成功加入:6
成功加入:1
成功加入:2
成功加入:7
输出:6
输出:1
输出:2
输出:7
成功加入:3
成功加入:8
输出:3
输出:8
成功加入:4
成功加入:9
输出:4
输出:9
成功加入:10
成功加入:5
输出:10
输出:5
 
这个迭代器很给力,一直处于等待和执行的状态,只要有新的元素被加入,它会找机会去执行foreach的内容,然后再阻塞去等新的元素。
 
而且在输出中,代码里的“完成枚举”字符串一直没有被输出。此时它还在卖力地等……因为它不确定什么时候才不会有新元素被加入。
 
 
 
返回目录
4. GetConsumingEnumerable和CompleteAdding
 
好,此时你应该想到了上面学的CompleteAdding方法,它可以禁止新的元素被加入到BlockingCollection的内部线程安全集合中,所以使用这个方法可以通知GetConsumingEnumerable的迭代器您老不用再等了,后面不会有元素被加进来了。
 
如下代码:
 
抱歉,这几段代码都不短,而且都类似。但我仍然把完整代码贴出来,虽然这使文章比较冗长,但是我觉得这样读者浏览或者复制时从上到下一目了然,总比看到诸如“请把前面xxx个代码做如下修改:把xxx行改成xxx,在xxx行加入这段代码……”好吧。
 
var bcollec = new BlockingCollection<int>();
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
用户名: 验证码:点击我更换图片
最新评论 更多>>

推荐热点

  • 浅析.NET下XML数据访问新机制
  • asp.net 面试+笔试题目第1/2页
  • C# 邮件地址是否合法的验证
  • C#高级编程:数据库连接[1]
  • asp.net 设置GridView的选中行的实现代码
  • 经典C++程序1
  • IIS 自动回收导致后台定时器失效的问题解决
  • ASP.NET&#160;GridView列表代码示例
  • 微软ASP.NET站点部署指南(3):使用Web.Config文件的Transforma
网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
Copyright © 2008-2015 计算机技术学习交流网. 版权所有

豫ICP备11007008号-1