一、概述:

System.Collections.Concurrent 命名空间提供多个线程安全集合类。

当有多个线程并发访问集合时,应使用这些类代替 System.CollectionsSystem.Collections.Generic 命名空间中的对应类型。

为了对集合进行线程安全的访问,定义了 IProducerConsumerCollection<T>接口。这个接口中最重 要的方法是TryAdd()和TryTake()。

  1. TryAdd()方法尝试给集合添加一项,但如果集合禁止添加项,这个操作就可能失败。为了给出相关信息,TryAdd()方法返回一个布尔值,以说明操作是成功还是失败。
  2. TryTake()方法也以这种方式工作,以通知调用者操作是成功还是失败,并在操作成功时返回集合中的项。

二、空间中包含的类

ConcurrentXXX :这些集合是线程安全的,如果某个动作不适用于线程的当前状态,它们就返回false。在继续之前,总是霈要确认添加或提取元素是否成功。不能相信集合会完成任务。

1、ConcurrentQueue<T> 队列

这个集合类用一种免锁定的算法实现,使用在内部合并到一个链表中的32项数组。

访问队列元素的方法有Enqueue()、TryDequeue()和TryPeek()。这些方法的命名非常类似于前面Queue<T>类的方法,只是给可能调用失败的方法加上了前缀Try。

因为这个类实现了IProducerConsumerCollection<T>接口,所以 TryAdd()和 TryTake()方法仅调用 Enqueue()和 TryDequeue()方法。

2、ConcurrentStack<T> 堆栈

非常类似于ConcurrentQueue<T>类,只是带有另外的元素访问方法。

ConcurrcntStack<T>类定义了 Push()、PushRange()、TryPeek()、TiyPop()和 TryPopRange() 方法。在内部这个类使用其元素的链表。

3、ConcurrentBag<T> 包

该类没有定义添加或提取项的任何顺序。这个类使用一个把线程映射到内部使用的数组上的概念,因此尝试减少锁定。

访问元素的方法有Add()、TryPeek()和 TryTake()。

4、ConcurrentDictionary<TKey, TValue> 字典

——这是一个线程安全的键值集合。

TryAdd()、TryGetValue()、TryRemove()和TryUpdate()方法以非阻塞的方式访问成员。

因为元素基于键和值, 所以 ConcurrentDictionary<TKey,TValue>没有实现 IProducerConsumerCollection<T>。

5、BlockingCollection<T> 集合

这个集合在可以添加或提取元素之前,会阻塞线程并一直等待。

BlockingCollection<T>集合提供了一个接口,以使用Add()和Take()方法来添加和删除元素。 这些方法会阻寒线程,一直等到任务可以执行为止。

Add()方法有一个重载版本,其中可以给该重载版本传递一个CancellationToken令牌。

这个令牌允许取消被阻塞的调用。如果不希望线程无限期地等待下去,且不希望从外部取消调用,就可以使用TryAdd()和 TryTake()方法,在这些方法中,也可以指定一个超时值,它表示在调用失败之前应阻塞线程和等待的最长时间。

6、BlockingCollection<T> 阻塞式集合

这是对实现了 IProducerConsumerCollection<T>接口的任意类的修饰器,它默认使用ConcurrentQueue<T>类。

还可以给构造函数传递任何其他实现了 IProducerConsumerCollection<T> 接口的类。

下面的代码示例简单演示了使用BlockingCollection<T>类和多个线程的过程。

一个线程是生成器,它使用Add()方法给集合写入元素,另一个线程是使用者,它使用Take()方法从集合中提取元素:

internal static BlockingCollection<int> _TestBCollection;
class ThreadWork1  // 生产者
{
public ThreadWork1()
{ }
public void run()
{
System.Console.WriteLine("ThreadWork1 run { ");
for (int i = 0; i < 100; i++)
{
System.Console.WriteLine("ThreadWork1 producer: " + i);
_TestBCollection.Add(i);
}
_TestBCollection.CompleteAdding();
System.Console.WriteLine("ThreadWork1 run } ");
}
}
class ThreadWork2  // 消费者
{
public ThreadWork2()
{ }
public void run()
{
int i = 0;
int nCnt = 0;
bool IsDequeuue = false;
System.Console.WriteLine("ThreadWork2 run { ");
while (!_TestBCollection.IsCompleted)
{
IsDequeuue = _TestBCollection.TryTake(out i);
if (IsDequeuue)
{
System.Console.WriteLine("ThreadWork2 consumer: " + i * i + " =====" + i);
nCnt++;
}
}
System.Console.WriteLine("ThreadWork2 run } ");
}
}
static void StartT1()
{
ThreadWork1 work1 = new ThreadWork1();
work1.run();
}
static void StartT2()
{
ThreadWork2 work2 = new ThreadWork2();
work2.run();
}
static void Main(string[] args)
{
Task t1 = new Task(() => StartT1());
Task t2 = new Task(() => StartT2());
_TestBCollection = new BlockingCollection<int>();//可以跟容量
Console.WriteLine("Sample 4-4 Main {");
Console.WriteLine("Main t1 t2 started {");
t1.Start();
t2.Start();
Console.WriteLine("Main t1 t2 started }");
Console.WriteLine("Main wait t1 t2 end {");
Task.WaitAll(t1, t2);
Console.WriteLine("Main wait t1 t2 end }");
Console.WriteLine("Sample 4-4 Main }");
}

并发集合 System.Collections.Concurrent 命名空间的更多相关文章

  1. C# 经典入门12章-System.Collections.Generic命名空间

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAtUAAAAsCAIAAAAl09PEAAAgAElEQVR4nOx95Vscyd7285cMPrg7Aw ...

  2. FCL研究-集合- System.Collections 接口和对象集合

    [目录] 发现自己已经有很长一段时间写代码没什么进步了,随便读读FCL的源码,看看之前一直用的方法是如何实现的,也顺便提高下自己.FCL很是庞大,很难下口,于是用最笨的办法,先看常见的命名空间,逐个展 ...

  3. 未能加载文件或程序集“System.Collections.Concurrent”或它的某一个依赖项。

    未能加载文件或程序集“XXXXXX”或它的某一个依赖项.试图加载格式不正确的程序.   在本机WIN7机器上的WebService部署到Win2008R2上发现错误 “/”应用程序中的服务器错误. 未 ...

  4. .Net Framework System.Collections 集合类

    本文内容 集合类 性能 最近复习了一下集合,C# 关于集合的类蛮多,但我除了 List 那几个经常用之外,其他的用得还真不多(只在小范围使用),但其实,每个集合类都各有自己适用的场景,功能也很强大.尤 ...

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

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

  6. [.Net] 什么是线程安全的并发集合

    System.Collections.Concurrent 为此,在.NET Framework中提供了System.Collections.Concurrent新的命名空间可以访问用于解决线程安全问 ...

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

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

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

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

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

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

随机推荐

  1. js 页面间的通信

    看了一下公司原来的代码,原页面ajax post返回一个页面完整的HTML,然后再打开一个新页面并输出ajax返回的所有代码到新页面上,在新页面上以表单提交的形式实现重定向. 任凭我想了半天也没想出来 ...

  2. JAVA练手--String

    package tet; public class kk { public static void main(String[] args) { //1. { String Stra = "1 ...

  3. Nginx Open File Cache

    Nginx 的 open_file_cache 相关配置可以缓存静态文件的元信息,在这些静态文件被频繁访问时可以显着提升性能. 被缓存的文件元信息包括: fd,文件被打开一次后,fd保留使用 size ...

  4. REDIS与MEMCACHED的区别 8大点

    如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储.2 Redis支持数据 ...

  5. 通过POST请求上传文件

    转自:https://blog.csdn.net/zhangge3663/article/details/81218488 理论 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交 ...

  6. 使用原生JavaScript实现对select增加option标签并附加value属性

    好久没有写原生的东西了,今天写了一个小项目里面包含着option选项,所以我决定使用原生JavaScript动态生成, 本着互联网分享精神,我将本篇文章分享给大家. html代码(就是一个select ...

  7. redisTemplate 总结

    依赖jar包 jackson <dependency> <groupId>com.fasterxml.jackson.core</groupId> <arti ...

  8. Luogu4887 第十四分块(前体)

    sto \(lxl\) orz 考虑莫队,每次移动端点,我们都要询问区间内和当前数字异或有 \(k\) 个 \(1\) 的数字个数 询问 \([l,r]\) 可以再次离线,拆成询问 \([1,l-1] ...

  9. C语言中关键词static的用法与作用域

    一.面向过程设计中的static 转载:http://blog.csdn.net/celerylxq/article/details/6160499 1.静态全局变量 在全局变量前,加上关键字stat ...

  10. 结对编程项目总结(core2组)

    结对编程项目总结(core2组) 作业---四则运算(Core 第二组)   ----by 吴雪晴 PB16061514 齐天杨 PB16060706 一.项目简介 项目的任务为制作一个给(貌似是?) ...