c#中集合类的线程安全问题

Acettest 2017-08-09 08:55:21
以下内容引用自MSDN:
Remarks
The wrapper returned by this method locks the queue before an operation is performed so that it is performed in a thread-safe manner.
To guarantee the thread safety of the Queue, all operations must be done through this wrapper only.
Enumerating through a collection is intrinsically not a thread-safe procedure. Even when a collection is synchronized, other threads can still modify the collection, which causes the enumerator to throw an exception. To guarantee thread safety during enumeration, you can either lock the collection during the entire enumeration or catch the exceptions resulting from changes made by other threads.
Examples
The following code example shows how to lock the collection using the SyncRoot during the entire enumeration. This method is an O(1) operation.
Queue myCollection = new Queue();
lock(myCollection.SyncRoot)
{
foreach (object item in myCollection)
{
// Insert your code here.
}
}
这是不是说,即使使用了Queue.Synchronized Method (Queue)方法来包装一个集合类,也无法确保集合的线程安全?
...全文
517 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2017-08-09
  • 打赏
  • 举报
回复
引用 9 楼 u010178308 的回复:
请恕小生愚钝,从您的回答中我还是没理解到底要不要在遍历queue时,对一个已经使用了Synchronized方法的queue加lock。
上面这个是msdn的解释。说白了,就是让你加Lock。 但其实本来就有线程安全的集合,你为何不使用?
浪子-无悔 2017-08-09
  • 打赏
  • 举报
回复
引用 7 楼 hanjun0612 的回复:
若要确保的线程安全性 Queue, ,必须通过返回的包装器执行所有操作 Synchronized 方法。 枚举整个集合本质上不是一个线程安全的过程。 即使某个集合已同步,其他线程仍可以修改该集合,这会导致枚举数引发异常。 若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常
咱还是少用这么复杂的玩意吧,别把自己玩死了 哈哈!!
xuzuning 2017-08-09
  • 打赏
  • 举报
回复
C# 对所有集合类都提供有线程安全的版本 如要在线程中操纵全局的传统集合类,应该加锁(lock)而不是图侥幸
Acettest 2017-08-09
  • 打赏
  • 举报
回复
引用 1 楼 diaodiaop 的回复:
首先,十分感谢恩师为我解惑,同时,也很好奇,您此图是来源于哪本书的截图?可否告之以让小弟参考参考,谢谢
Acettest 2017-08-09
  • 打赏
  • 举报
回复
引用 7 楼 hanjun0612 的回复:
若要确保的线程安全性 Queue, ,必须通过返回的包装器执行所有操作 Synchronized 方法。 枚举整个集合本质上不是一个线程安全的过程。 即使某个集合已同步,其他线程仍可以修改该集合,这会导致枚举数引发异常。 若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常
请恕小生愚钝,从您的回答中我还是没理解到底要不要在遍历queue时,对一个已经使用了Synchronized方法的queue加lock。
Acettest 2017-08-09
  • 打赏
  • 举报
回复
引用 6 楼 xdashewan 的回复:
[quote=引用 5 楼 u010178308 的回复:] 那是不是说,如果我不使用迭代器,只用for来遍历集合,就不会引发线程安全问题呢?
Queue没有下标访问方式,用不用for循环有何区别呢,你可以看作仅仅是把正常的代码写在for循环里而已,所以不影响其线程安全性[/quote]谢谢,刚刚那个问题问的让我很难堪,抱歉抱歉
正怒月神 2017-08-09
  • 打赏
  • 举报
回复
若要确保的线程安全性 Queue, ,必须通过返回的包装器执行所有操作 Synchronized 方法。 枚举整个集合本质上不是一个线程安全的过程。 即使某个集合已同步,其他线程仍可以修改该集合,这会导致枚举数引发异常。 若要确保枚举过程中的线程安全性,可以在整个枚举期间锁定集合,或者捕获由其他线程进行的更改所导致的异常
xdashewan 2017-08-09
  • 打赏
  • 举报
回复
引用 5 楼 u010178308 的回复:
那是不是说,如果我不使用迭代器,只用for来遍历集合,就不会引发线程安全问题呢?
Queue没有下标访问方式,用不用for循环有何区别呢,你可以看作仅仅是把正常的代码写在for循环里而已,所以不影响其线程安全性
Acettest 2017-08-09
  • 打赏
  • 举报
回复
引用 4 楼 xdashewan 的回复:
我的理解是这样的,首先Queue.Synchronized方法返回的那个Queue是线程安全的,备注中提到的是当你使用foreach这样的枚举器的时候是线程不安全的,需要lock
那是不是说,如果我不使用迭代器,只用for来遍历集合,就不会引发线程安全问题呢?
xdashewan 2017-08-09
  • 打赏
  • 举报
回复
我的理解是这样的,首先Queue.Synchronized方法返回的那个Queue是线程安全的,备注中提到的是当你使用foreach这样的枚举器的时候是线程不安全的,需要lock
exception92 2017-08-09
  • 打赏
  • 举报
回复
使用lock可以保证当前只能有一个线程对其操作。 上边说的意思是迭代集合不是线程安全的,如果不用lock,其它线程操作集合会引发异常。用lock 不会造成操作结果混乱。
by_封爱 版主 2017-08-09
  • 打赏
  • 举报
回复
我的理解就是 线程安全集合 只是内部实现了lock而已. 所以 lock+非线程安全集合 ==线程安全集合
by_封爱 版主 2017-08-09
  • 打赏
  • 举报
回复
项目名称:高仿QQ2013通讯DEMO-10.30更新 版本号:10.30 最新版本 下载内容: (C#)CC2013局域网通讯源码一份, 可引用至工具箱最新版CSkin.dll-10.30版本界面库一份。 界面库更新说明: CC2013-10.30 1.由于SkinForm名字太多人使用,界面库命名正式改为CSkin.dll,官网www.cskin.net。 2.SkinTabControl标签添加菜单箭头,可点击展开菜单。 3.SkinTabControl添加标签关闭按钮。 4.修复部分文乱码问题。 5.优化好友列表右键菜单。 6.将窗体自定义系统按钮改为集合模式,可添加无数个自定义系统按钮。自定义系统按钮事件可以 e.参数 来判断。 7.增加360安全卫士-DEMO案例。 8.增加SkinAnimatorImg控件,用于支持位图动画的播放。如360的动态logo。 9.各种细节BUG优化。 CC2013-10.11 1.添加SkinTabControlEx,加入更加自定义的美化属性和动画效果。 2.添加SkinAnimator,通用动画控件。 3.添加Html编辑器控件 4.修复SkinButton图标和文本相对位置的BUG CC2013-9.26 1.优化好友列表CPU占用 2.好友列表加入好友登录平台属性:安卓 苹果 WEBQQ PC 3.优化标题绘制模式,新添标题绘制模式属性。 4.新添标题偏移度属性。 5.加入圆形进度条控件:ProgressIndicator。 CC2013-9.5.2 1.优化截图控件,截图工具栏加入新功能。 2.解决个人信息卡和天气窗体显示后不会消失的问题。 3.各种细节BUG优化。 CC2013-9.5.1 1.解决贴边左右隐藏的BUG。 2.解决窗体点击事件不能触发的问题。 3.优化SkinButton继承父容器背景色的代码。 4.解决SkinButton异常错误。 CC2013-9.3 1.好友列表右键菜单没反应问题。 2.新增美化控件SkinDatagridview。 3.密码软件盘回删不了文字问题。 4.双击窗体最大化,最大化后再双击恢复原大小,(win7)。 5.部分细节调优。 实现功能: 1.界面库多达25个自定义换肤控件,让每个控件设设属性就能达到你想要的效果,支持图片换肤和色调绘制。 2.四边阴影,毛边效果,可以设置阴影宽度和阴影颜色,支持所有系统。 3.拥有密码键盘输入,防护更贴心。 4.8种圆角窗体模式供你选择,淋漓尽致,润滑如圆。 5.登录主界面后,有登陆提示窗,提示上次登录的城市和时间。 6.皮肤随心变:拖动任意一张图片至主界面,就可以改变皮肤。 7.皮肤色调获取:改变皮肤的同时,将计算图片色调,再将其运用到窗体背景色。 8.皮肤尾部渐变:上下左右方均可实现,渐变皮肤。 9.皮肤拖拉方向:可以选择皮肤在拉伸的时候,粘着哪一边拖拉。 10.GDI+界面重绘,处理消息机制,3种移动模式和拉伸是否启用只需要设置一个属性的事就可以解决。 11.界面渐变闪现和闪退:不再像平凡的突然出现,采用API渐变机制,渐渐出现和消失,win7系统下还有动态缩小至任务的效果。 12.完美好友列表,可添加上千好友,不卡不掉线,还可以拖动好友到其他分组。 13.好友悬浮至头像可以查看详细资料卡。 14.窗口可调渐变后透明度:让窗体看起来更像是Vista玻璃窗体风格。 15.聊天窗口可发送图片,大文件,表情,还有震动。 16.按钮控件背景色拥有继承窗体背景主色调的功能,让整体色调保持一致。 17.更是有和如出一辙的扣扣截图。仿真度也达到100%,完美修复所有已知BUG。 18.聊天窗口,可以调字体颜色和字体样式等多项功能。 20.SkinLabel与SkinButton控件字体与窗体标题可以根据背景色暗亮度自动调节字体为黑还是白。 21.MessageBox提示框的美化,并继承调用窗口的色调与背景,MessageBox可所谓已达到帅气的不能再帅气的境界了。 22.天气皮肤自动变,所有窗体根据当地天气自动决定皮肤背景,CC最帅气功能之一。 23.个人资料卡及聊天窗体拥有动态CC秀展示。 24.主界面拖动换肤的同时,所关联的子窗体皮肤也会跟着变。 25.多线程大文件传输功能,支持无上限大文件传输,有进度条显示进程度。 26.界面库已封装了大图取主色调,颜色判断暗亮等多项功能。 27.如果你觉得获取天气让你的登录太慢不想要的话,注释相关调用方法即可快速登录。 界面库交流群:306485590 本人QQ:345015918 注意: Demo版不包括更新,为方便用户查看和使用属性等方法,dll只轻微加密。想反编译的就不要尝试了,里面有上百个类,改错改到你哭。 介意购买正版,永久更新配源码。 看截图或者想购买商业版的用户请访问以下地址: http://www.51aspx.com/code/TotalLikeQQ2013 特权:购买商业版的用户,有权利享有最快的更新服务,第一时间将最新版本的dll源码送到你手上。 使本项目源码或本项目生成的DLL前请仔细阅读以下协议内容,如果你同意以下协议才能使用本项目所有的功能,否则如果你违反了以下协议,有可能陷入法律纠纷和赔偿,作者保留追究法律责任的权利。 1、你可以在开发的软件产品使用和修改本项目的源码和DLL,但是请保留所有相关的版权信息。 2、不能将本项目源码与作者的其他项目整合作为一个单独的软件售卖给他人使用。 3、不能传播本项目的源码和DLL,包括上传到网上、拷贝给他人等方式。 4、以上协议暂时定制,由于还不完善,作者保留以后修改协议的权利。 时间:2013-7-5 作者: 乔克斯 请保留以上版权信息,否则作者将保留追究法律责任。

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧