转载地址:http://blog.csdn.net/wangzhiyu1980/article/details/45497907

此文为个人学习《C#并行编程高级教程》的笔记,总结并调试了一些文章中的代码示例。 在以后开发过程中可以加以运用。

对于并行任务,与其相关紧密的就是对一些共享资源,数据结构的并行访问。经常要做的就是对一些队列进行加锁-解锁,然后执行类似插入,删除等等互斥操作。 .NetFramework 4.0 中提供了一些封装好的支持并行操作数据容器,可以减少并行编程的复杂程度。

基本信息

.NetFramework中并行集合的名字空间: System.Collections.Concurrent

并行容器:

  • ConcurrentQueue
  • ConcurrentStack
  • ConcurrentBag : 一个无序的数据结构集,当不需要考虑顺序时非常有用。
  • BlockingCollection : 与经典的阻塞队列数据结构类似
  • ConcurrentDictionary
 
这些集合在某种程度上使用了无锁技术(CAS Compare-and-Swap和内存屏障 Memory Barrier),与加互斥锁相比获得了性能的提升。但在串行程序中,最好不用这些集合,它们必然会影响性能。
 
关于CAS: 
  • http://www.tuicool.com/articles/zuui6z
  • http://www.360doc.com/content/11/0914/16/7656248_148221200.shtml
关于内存屏障
  • http://en.wikipedia.org/wiki/Memory_barrier

用法与示例

ConcurrentQueue

其完全无锁,但当CAS面临资源竞争失败时可能会陷入自旋并重试操作。
 
  • Enqueue:在队尾插入元素
  • TryDequeue:尝试删除队头元素,并通过out参数返回
  • TryPeek:尝试将对头元素通过out参数返回,但不删除该元素。
 
程序示例:
 

ConcurrentStack

其完全无锁,但当CAS面临资源竞争失败时可能会陷入自旋并重试操作。
  • Push:向栈顶插入元素
  • TryPop:从栈顶弹出元素,并且通过out 参数返回
  • TryPeek:返回栈顶元素,但不弹出。
测试中一个有趣的现象:
 
虽然生产者已经在栈中插入值已经到了25,但消费者第一个出栈的居然是4,而不是25。很像是出错了。但仔细想想入栈,出栈和打印语句是两个部分,而且并不是原子操作,出现这种现象应该也算正常。
 

ConcurrentBag

一个无序的集合,程序可以向其中插入元素,或删除元素。
在同一个线程中向集合插入,删除元素的效率很高。
 
  • Add:向集合中插入元素
  • TryTake:从集合中取出元素并删除
  • TryPeek:从集合中取出元素,但不删除该元素。
 
程序示例:
 

BlockingCollection

一个支持界限和阻塞的容器
 
  • Add :向容器中插入元素
  • TryTake:从容器中取出元素并删除
  • TryPeek:从容器中取出元素,但不删除。
  • CompleteAdding:告诉容器,添加元素完成。此时如果还想继续添加会发生异常。
  • IsCompleted:告诉消费线程,生产者线程还在继续运行中,任务还未完成。
 
示例程序:
 
程序中,消费者线程完全使用  while (!_TestBCollection.IsCompleted) 作为退出运行的判断条件。
在Worker1中,有两条语句被注释掉了,当i 为50时设置CompleteAdding,但当继续向其中插入元素时,系统抛出异常,提示无法再继续插入。
 
当然可以尝试在Work1中注释掉 CompleteAdding 语句,此时Work2陷入循环无法退出。
 

ConcurrentDictionary

对于读操作是完全无锁的,当很多线程要修改数据时,它会使用细粒度的锁。
  • AddOrUpdate:如果键不存在,方法会在容器中添加新的键和值,如果存在,则更新现有的键和值。
  • GetOrAdd:如果键不存在,方法会向容器中添加新的键和值,如果存在则返回现有的值,并不添加新值。
  • TryAdd:尝试在容器中添加新的键和值。
  • TryGetValue:尝试根据指定的键获得值。
  • TryRemove:尝试删除指定的键。
  • TryUpdate:有条件的更新当前键所对应的值。
  • GetEnumerator:返回一个能够遍历整个容器的枚举器。
 

C# 并行编程 之 并发集合 (.Net Framework 4.0)(转)的更多相关文章

  1. 【C#】58. .Net中的并发集合——BlockingCollection

    https://blog.csdn.net/huiwuhuiwu/article/details/53608269 这篇是并发集合中的最后一篇,介绍一下BlockingCollection.在工作中我 ...

  2. C#中的多线程 - 并行编程 z

    原文:http://www.albahari.com/threading/part5.aspx 专题:C#中的多线程 1并行编程Permalink 在这一部分,我们讨论 Framework 4.0 加 ...

  3. 并行编程(Parallel Framework)

    前言 并行编程:通过编码方式利用多核或多处理器称为并行编程,多线程概念的一个子集. 并行处理:把正在执行的大量的任务分割成小块,分配给多个同时运行的线程.多线程的一种. 并行编程分为如下几个结构: 1 ...

  4. C#并行编程-并发集合

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  5. 《C#并行编程高级教程》第4章 并发集合 笔记

    这一章主要介绍了System.Collections.Concurrent下的几个类. ConcurrentQueue<T> 并发队列.完全无锁,使用CAS(compare-and-swa ...

  6. 转载 .Net多线程编程—并发集合 https://www.cnblogs.com/hdwgxz/p/6258014.html

    集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全的, ...

  7. .Net多线程编程—并发集合

    并发集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全 ...

  8. 【读书笔记】.Net并行编程(三)---并行集合

    为了让共享的数组,集合能够被多线程更新,我们现在(.net4.0之后)可以使用并发集合来实现这个功能.而System.Collections和System.Collections.Generic命名空 ...

  9. C#并发编程之初识并行编程

    写在前面 之前微信公众号里有一位叫sara的朋友建议我写一下Parallel的相关内容,因为手中商城的重构工作量较大,一时之间无法抽出时间.近日,这套系统已有阶段性成果,所以准备写一下Parallel ...

随机推荐

  1. 武汉科技大学ACM:1003: 华科版C语言程序设计教程(第二版)例题6.6.改编

    Problem Description 小明明最喜欢学英语了,英语课从来不翘课,但是英语却一直没学好,因为上课一直在睡觉.为什么会睡觉呢,因为他觉得英文单词太长了.现在小明明有一个很长很长很长的单词, ...

  2. 26.单片机中利用定时器中断,在主流程while(1){}中设置每隔精确时间计量

    { CountMilliseconds++;//只负责自加,加到最大又重新从0开始 } u16 setDelay(u16 t) { ); } u8 checkDelay (u16 t)//返回非零表示 ...

  3. JavaScript 本地对象、内置对象、宿主对象

    首先解释下宿主环境:一般宿主环境由外壳程序创建与维护,只要能提供js引擎执行的环境都可称之为外壳程序.如:web浏览器,一些桌面应用系统等.即由web浏览器或是这些桌面应用系统早就的环境即宿主环境. ...

  4. PHPCMSv9 更改后台地址(测试)

    最新发布的PHPCMS V9由于采用了MVC的设计模式,所以它的后台访问地址是固定的,虽然可以通过修改路由配置文件来实现修改,但每次都修改路由配置文件对于我来说有点麻烦了,而且一不小心就会出错.这里使 ...

  5. PHPの页面跳转-常见方法

    PHP页面跳转一.header()函数 header()函数是PHP中进行页面跳转的一种十分简单的方法.header()函数的主要功能是将HTTP协议标头(header)输出到浏览器. header( ...

  6. d029: 求出2-100之间的所有质数(素数)

    内容: 求出2-100之间的所有质数(素数) 输入说明: 无 输出说明: 一行一个素数 /* 质数又称素数.指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数(不包括0)整除的数. */ ...

  7. 前端MVC学习笔记(一)——MVC概要与angular概要、模板与数据绑定

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.AngularJS是框架而jQuery则是库. 1.2. ...

  8. app 测试点

    以下所有测试最后必须在真机上完整的执行1.安装.卸载测试 在真机上的以及通过91等第三方的安装与卸载 安装在手机上还是sd卡上 2.启动app测试3.升级测试 数字签名.升级覆盖安装.下载后手动覆盖安 ...

  9. javascript scroll事件

    http://developer.51cto.com/art/201107/277994.htm onscroll事件 window.onscroll|| document.onscroll var ...

  10. 当分页语句遇到union all

    SELECT * FROM (SELECT pubformdat0_.id id332_, pubformdat0_.domain_id domain2_332_, pubformdat0_.proc ...