C#中的并发集合Concurrent类_第1页
C#中的并发集合Concurrent类_第2页
C#中的并发集合Concurrent类_第3页
C#中的并发集合Concurrent类_第4页
C#中的并发集合Concurrent类_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第C#中的并发集合Concurrent类System.Collections.Concurrent命名空间提供多个线程安全集合类。

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

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

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

二、空间中包含的类

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

1、ConcurrentQueue队列

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

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

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

2、ConcurrentStack堆栈

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

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

3、ConcurrentBag包

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

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

4、ConcurrentDictionary字典

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

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

因为元素基于键和值,所以ConcurrentDictionary没有实现IProducerConsumerCollection。

5、BlockingCollection集合

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

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

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

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

6、BlockingCollection阻塞式集合

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

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

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

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

internalstaticBlockingCollectionint_TestBCollection;

classThreadWork1//生产者

publicThreadWork1()

publicvoidrun()

System.Console.WriteLine("ThreadWork1run{");

for(inti=0;i100;i++)

System.Console.WriteLine("ThreadWork1producer:"+i);

_TestBCollection.Add(i);

_TestBCollection.CompleteAdding();

System.Console.WriteLine("ThreadWork1run}");

classThreadWork2//消费者

publicThreadWork2()

publicvoidrun()

inti=0;

intnCnt=0;

boolIsDequeuue=false;

System.Console.WriteLine("ThreadWork2run{");

while(!_TestBCollection.IsCompleted)

IsDequeuue=_TestBCollection.TryTake(outi);

if(IsDequeuue)

System.Console.WriteLine("ThreadWork2consumer:"+i*i+"====="+i);

nCnt++;

System.Console.WriteLine("ThreadWork2run}");

staticvoidStartT1()

ThreadWork1work1=newThreadWork1();

work1.run();

staticvoidStartT2()

ThreadWork2work2=newThreadWork2();

work2.run();

staticvoidMain(string[]args)

Taskt1=newTask(()=StartT1());

Taskt2=newTask(()=StartT2());

_TestBCollection=newBlockingCollectionint//可以跟容量

Console.WriteLine("Sample4-4Main{");

Console.WriteLine("Maint1t2started{");

t1.Start();

t2.Start();

Console.WriteLine("Maint1t2started}");

Console.WriteLine("Mainwaitt1t2end{");

Task.WaitA

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论