博客
关于我
C#线程安全集合类说明(1): BlockingCollection<T>
阅读量:523 次
发布时间:2019-03-08

本文共 2758 字,大约阅读时间需要 9 分钟。

线程安全的集合所在的命名空间 using System.Collections.Concurrent;

Concurrent意思是并发的,并行的。反义是sequential(顺序的),线程安全的意思就是多线程中的同步

System.Collections.Concurrent 命名空间

System.Collections.Concurrent 命名空间提供多个线程安全集合类。当有多个线程并发访问集合时,应使用这些类代替  和  命名空间中的对应类型。 但是,不保证通过扩展方法或通过显式接口实现访问集合对象是线程安全的,可能需要由调用方进行同步。

为实现  的线程安全集合提供阻塞和限制功能。

表示对象的线程安全的无序集合。

表示可由多个线程同时访问的键/值对的线程安全集合。

表示线程安全的先进先出 (FIFO) 集合。

表示线程安全的后进先出 (LIFO) 集合。

表示将可排序数据源拆分为多个分区的特定方式。

提供针对数组、列表和可枚举项的常见分区策略。

表示将数据源拆分为多个分区的特定方式。

接口

接口

定义供制造者/使用者用来操作线程安全集合的方法。 此接口提供一个统一的表示(为生产者/消费者集合),从而更高级别抽象如  可以使用集合作为基础的存储机制。

枚举

枚举

指定控制分区程序的缓冲行为的选项。

 

参考微软官方文档:

5

参考源代码(类BlockingCollection<T>)

一、示例:BlockingCollection<T> ,该类与队列类似。

源程序:

using System;

using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadSafeCollectionDemo

{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("测试阻塞集合BlockingCollection的添加【Add】和移除【Take】...");
            Task task = AddTakeBlockingCollectionAsync();
            Task.WaitAll(task);
            Console.WriteLine("下面测试阻塞集合BlockingCollection的尝试移除【TryTake】...");
            TryTakeBlockingCollection();
            Console.ReadLine();
        }

        /// <summary>

        /// 阻塞集合BlockingCollection的Add(添加)和Take(移除):生产者【添加元素】、消费者【移除元素】线程安全同时操作
        /// </summary>
        /// <returns></returns>
        static async Task AddTakeBlockingCollectionAsync()
        {
            using (BlockingCollection<int> blockingCollection = new BlockingCollection<int>())
            {
                //生产者
                Task taskProducer = Task.Run(() => 
                {
                    //添加一个元素
                    blockingCollection.Add(1);
                    blockingCollection.Add(2);
                    blockingCollection.Add(3);
                    //结束添加元素:集合已标记为完成添加。CompleteAdding()方法会导致Take()方法出现移除操作异常
                    blockingCollection.CompleteAdding();
                });
                //消费者
                Task taskConsumer = Task.Factory.StartNew(() => 
                {
                    try
                    {
                        while (true)
                        {
                            //移除一个元素,并返回这个移除的元素
                            int removeItem = blockingCollection.Take();
                            Console.WriteLine(removeItem);
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"移除项出现异常:{ex.Message}");
                    }
                });
                await Task.WhenAll(taskProducer, taskConsumer);
            }
        }

        /// <summary>

        /// 尝试移除阻塞集合BlockingCollection中的元素
        /// </summary>
        static void TryTakeBlockingCollection()
        {
            using (BlockingCollection<int> bc = new BlockingCollection<int>())
            {
                for (int i = 0; i < 1000; i++)
                {
                    bc.Add(i);
                }
                Console.WriteLine($"是否完成添加:【{bc.IsAddingCompleted}】");
                bc.CompleteAdding();//标记集合已经完成添加
                Console.WriteLine($"是否完成添加:【{bc.IsAddingCompleted}】");

                int outerSum = 0;

                Action action = new Action(() =>
                {
                    int localItem;
                    int sum = 0;
                    while (bc.TryTake(out localItem))
                    {
                        sum += localItem;
                    }
                    Interlocked.Add(ref outerSum, sum);
                    Console.WriteLine($"求和Sum={sum},当前替换:【{outerSum}】");
                });

                //并行操作:三个委托同时执行

                //相当于 将数组求和 分 三小部分数组 分别求和,最后合并
                Parallel.Invoke(action, action, action);
                Console.WriteLine($"此时outerSum为【{outerSum}】");
                Console.WriteLine($"此时集合已完成添加并且集合为空:【{bc.IsCompleted}】");
            }
        }

    }

}

程序运行如图:

 

 

 

 

 

 

转载地址:http://xvqnz.baihongyu.com/

你可能感兴趣的文章
Luogu2973:[USACO10HOL]赶小猪
查看>>
mabatis 中出现&lt; 以及&gt; 代表什么意思?
查看>>
Mac book pro打开docker出现The data couldn’t be read because it is missing
查看>>
MAC M1大数据0-1成神篇-25 hadoop高可用搭建
查看>>
mac mysql 进程_Mac平台下启动MySQL到完全终止MySQL----终端八步走
查看>>
Mac OS 12.0.1 如何安装柯美287打印机驱动,刷卡打印
查看>>
MangoDB4.0版本的安装与配置
查看>>
Manjaro 24.1 “Xahea” 发布!具有 KDE Plasma 6.1.5、GNOME 46 和最新的内核增强功能
查看>>
mapping文件目录生成修改
查看>>
MapReduce程序依赖的jar包
查看>>
mariadb multi-source replication(mariadb多主复制)
查看>>
MariaDB的简单使用
查看>>
MaterialForm对tab页进行隐藏
查看>>
Member var and Static var.
查看>>
memcached高速缓存学习笔记001---memcached介绍和安装以及基本使用
查看>>
memcached高速缓存学习笔记003---利用JAVA程序操作memcached crud操作
查看>>
Memcached:Node.js 高性能缓存解决方案
查看>>
memcache、redis原理对比
查看>>
memset初始化高维数组为-1/0
查看>>
Metasploit CGI网关接口渗透测试实战
查看>>