博客
关于我
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/

你可能感兴趣的文章
mysql slave 停了_slave 停止。求解决方法
查看>>
MySQL SQL 优化指南:主键、ORDER BY、GROUP BY 和 UPDATE 优化详解
查看>>
MYSQL sql语句针对数据记录时间范围查询的效率对比
查看>>
mysql sum 没返回,如果没有找到任何值,我如何在MySQL中获得SUM函数以返回'0'?
查看>>
mysql Timestamp时间隔了8小时
查看>>
Mysql tinyint(1)与tinyint(4)的区别
查看>>
mysql union orderby 无效
查看>>
mysql v$session_Oracle 进程查看v$session
查看>>
mysql where中如何判断不为空
查看>>
MySQL Workbench 使用手册:从入门到精通
查看>>
mysql workbench6.3.5_MySQL Workbench
查看>>
MySQL Workbench安装教程以及菜单汉化
查看>>
MySQL Xtrabackup 安装、备份、恢复
查看>>
mysql [Err] 1436 - Thread stack overrun: 129464 bytes used of a 286720 byte stack, and 160000 bytes
查看>>
MySQL _ MySQL常用操作
查看>>
MySQL – 导出数据成csv
查看>>
MySQL —— 在CentOS9下安装MySQL
查看>>
MySQL —— 视图
查看>>
mysql 不区分大小写
查看>>
mysql 两列互转
查看>>