C#线程安全使用(二)

小编 2026-06-24 阅读:599 评论:0
刚才想了半天文章应该起什么名字,最后决定起名为《线程安全使用》,线程安全这个词很难理解,感觉就像...

刚才想了半天文章应该起什么名字,最后决定起名为《线程安全使用》,线程安全这个词很难理解,感觉就像托管这词一样,但是托管翻译成英文是managed,我通常把他翻译成被管理,这样就好理解多了,线程安全也是一样,可以理解为可以被多个线程同时使用的集合,而且同时使用的时候是该集合的值是准确的。

MSDN将在System.Collections.Concurrent命名空间下的集合,都称为线程安全的集合。

下面举一个使用线程安全集合的例子,使用的是BlockingCollection,个人觉得这个集合是够用了,其他集合和这个集合基本上大同小异,没什么大区别。但是根据官方解释ConcurrentBag是适用于快速删除和添加,具体为什么他适用,而BlockingCollection不适用,我也没找到原因。

C#线程安全使用(二)C#线程安全使用(二)
using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;using System.Threading.Tasks;namespace ParallelConsole{    class Program    {                //定义集合大小为51个,也可以不定义大小        static BlockingCollection<int> blocking = new BlockingCollection<int>(51);              static void Main(string[] args)        {                        blocking = new BlockingCollection<int>();            Console.WriteLine("当前blocking为:" + blocking.IsCompleted + "设置了集合大小count一样是0,blocking.Count:" + blocking.Count());            //当前线程标识            Console.WriteLine(Thread.CurrentThread.GetHashCode());            for (int i = 0; i < 3; i++)            {                ////如果添加到第3个,就设置添加完成,这时在添加就会抛异常                //if (i == 3)                //{                //    blocking.CompleteAdding();                //}                              Action<object> action = new Action<object>(run);                Task task = new Task(action,i);                 task.RunSynchronously();             }            Console.WriteLine("设置添加完成前:" + blocking.IsAddingCompleted);            //设置添加完成后            blocking.CompleteAdding();            Console.WriteLine("设置添加完成后:" + blocking.IsAddingCompleted);            #region 同步取 取3个            //for (int i = 0; i < 3; i++)            //{            //    Action actionTake = new Action(take);            //    actionTake();            //}            #endregion            //并发读取                        #region 并发步取 取3个            //blocking.IsCompleted 只有当集合被添加进内容,然后又都被取光了以后,他才会等于ture,否则都是false            //当IsCompleted为ture时,就不能再取了否则会抛异常                        //同时取,结果是             //blocking:0            //blocking:2            //blocking:1            if (!blocking.IsCompleted)//如果集合没取光            {                Action actionTake2 = new Action(take);                Parallel.Invoke(actionTake2, actionTake2, actionTake2);            }            #endregion            Console.WriteLine("当前blocking为:" + blocking.IsCompleted +  ",blocking数量为:" + blocking.Count());            //数据被取光了以后, blocking.Count()为0            Console.Read();        }        public static void take()        {            //同步取,blocking.Count()会真实的表现,而异步取,Count是不准确的,因为我取count的时候,可能集合已经又被取出数据了,测试10次肯定会出现不真实的情况            Console.WriteLine("blocking:" + blocking.Take() + ",blocking数量为:" + blocking.Count());        }        public static void run(object i)        {            int currentI = int.Parse(i.ToString());            blocking.TryAdd(currentI);         }    }}
View Code

解释几个方法:

 Parallel.Invoke(),并发调用ACtion,可以传多个action,也可以传一个action数据组。

 Task(action<t>,object),这是Task的构造方法,接受action,注意object是action的参数,但是解释中并没有说的很明白。(翻译坑,你懂的),根据MSDN提供的构造方法,并没有接受action<t,t>,action<t,t,t>这样的,也就是说,定义函数时,要传递一个实体,而不要传递多个参数,否则任务调用不了。

 task.RunSynchronously(),根据MSDN解释,他是同步运行任务计划用的,同时他和task.Start()一样,也可以启动线程。

BlockingCollection集合

属性一:IsCompleted,他是表示集合是否有数据,只有当集合被添加进内容,然后又都被取光了以后,他才会等于ture,否则都是false。

PS:这个解释如果你要看MSDN一辈子都想不明白,msdn的中文翻译真心坑。

属性一:BlockingCollection.IsAddingCompleted,表示是否添加完成。针对blocking.CompleteAdding()的使用,当调用了该方法IsAddingCompleted就为true。

方法一:BlockingCollection.blocking.CompleteAdding(),设置IsAddingCompleted用的。

方法二:BlockingCollection.Add,添加一个实体

方法三:BlockingCollection.TryAdd,添加一个实体,我这里用的是这个方法,区别是,如果添加重复项,他会引发InvalidOperationException这个异常。

方法四:BlockingCollection.Take,从集合中取一个值,注意,是真的取出来,取出来后,BlockingCollection.cout会减一。

运行结果如下:

C#线程安全使用(二)

今天先写到这,写文字还真是累,明明没写几个字。。。

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

上一篇:12.23总结 下一篇:多线程
热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表