请问C# LINQ 的select方法,是不是多线程安全的?

刘欣的博客 2015-05-02 08:04:05

比如我有一个全局变量list叫herolist, 我要对它查询,是在多线程中,


var h = (from obj in gv.herolist where obj.playername == “haha” select obj).FirstOrDefault();



请问C# LINQ 的select方法,是不是多线程安全的?

如果不是,是否我应该在执行这条语句之前做点什么? 比如lock (){} ?
...全文
565 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
刘欣的博客 2015-05-05
  • 打赏
  • 举报
回复
to assiwe : 用TreadStatic属性. 我查了一下TreadStatic 的作用,是让不同的线程拥有不同的list值。 但我有一个问题: 我的list,我保证没有其它的语句改变它, 只使用SELECT。 还需要 TreadStatic吗?
刘欣的博客 2015-05-05
  • 打赏
  • 举报
回复
【再补充】 这些线程,是并行或乱序执行的,不是依次执行的!!!
刘欣的博客 2015-05-05
  • 打赏
  • 举报
回复
首先感谢SP1234,很热心的帮助。感谢assiwe,好像你说中了我想要的....... 可能是我没有说清楚我的问题。 【环境前提】 我有一个list 我用线程1 使用LINQ 的SELECT去查询它 我用线程2 使用LINQ 的SELECT去查询它 我用线程3 使用LINQ 的SELECT去查询它 我用线程4 使用LINQ 的SELECT去查询它 .... 我用线程N 使用LINQ 的SELECT去查询它 请注意,这些线程只执行SELECT!!! 【我的问题】 我在上述线程中,需要做其它事情来保证操作安全不???
moonwrite 2015-05-05
  • 打赏
  • 举报
回复
和15楼的观点一样 只是查询~~~根本不用考虑是否线程安全~~ 哪怕是A查到一半 交给B来查询 没有什么问题
刘欣的博客 2015-05-05
  • 打赏
  • 举报
回复
引用 15 楼 Z65443344 的回复:
不管是变量还是数组,是引用类型还是值类型 只读取,不赋值,会涉及到线程安全不安全的问题?
我使用了读写锁控制对全局变量的读取和写入, 在多个读取线程中,不会对全局变量有写操作。 我的问题就是,这些读线程中使用了LINQ的select方法,请问需要做其它事情来保证操作安全吗???
於黾 2015-05-05
  • 打赏
  • 举报
回复
不管是变量还是数组,是引用类型还是值类型 只读取,不赋值,会涉及到线程安全不安全的问题?
  • 打赏
  • 举报
回复
你所谓“linq 是不是多线程安全的”的问题说白了,也就是像让别人告诉你说“不用设计线程同步 lock 语句了”。但是不蒙你的话,它“是”线程安全的,但是丝毫不影响你“必须在必要时写 lock 语句”。因为二者根本无关。有的人是刚学习,所以不知道;而更多的人是知道的名词儿太多了,但是完全用错误概念方式来干扰应做的正确设计,这有时候比不知道概念的人还糊涂。
  • 打赏
  • 举报
回复
有哪一个不需要在多线程操作并且有线程修改的情况下不需要写lock的 --> 有哪一个不需要在多线程操作并且有线程修改的情况下写lock的 msdn上声明为“线程安全的”的对象,你使用时在照样在必要时要写 lock 语句的。根本就是无关的两个机制。
  • 打赏
  • 举报
回复
在.net中几乎没有什么东西会在毫无必要的情况去写 lock,甚至在多个无法预知运行次序、间隔时间的操作之间还给你保持什么“线程安全的”概念。实际上这个说法就是自欺欺人的。 你看看msdn上所有声明为“线程安全的”对象/组件,有哪一个不需要在多线程操作并且有线程修改的情况下不需要写lock的? 写lock是基本常识,不要用“线程安全的”这种貌似接近而实际上无关的名词儿来干扰最基本的设计概念。
assiwe 2015-05-03
  • 打赏
  • 举报
回复
不要这么写. 所有的linq 最后都会落到迭代器上去, List的迭代器不是线程安全的. 所以这么写即使只有查询也很可能会出问题. 取决于你的需求, 你可以 1. 用TreadStatic属性, 让每个线程里有自己的一份List. 2 在list上加锁 3 用System.Collections.Concurrent空间里的类代替List
devmiao 2015-05-02
  • 打赏
  • 举报
回复
如果使用的都是局部变量,并且集合本身没有被共享的话,是的
  • 打赏
  • 举报
回复
引用 4 楼 ot512csdn 的回复:
如果只用SELECT查询数据时,在多线程里面是安全的,那就再好不过了,谢谢各位帮帮忙。
你另外发明了一个属于你自己的“在多线程里面是安全的”的名词儿,而完全没有去考虑别人为什么要提到“lock”。写lock必定是有需要写lock的条件,在其它线程改变herolist 时,Linq没有什么办法让你不用写Lock。但是这没有理由说成是linq线程不安全。
  • 打赏
  • 举报
回复
所谓“线程安全的”,拿 List<T> 来举例,是说当一个线程从集合中删除一个对象,另外有一个线程读取它的 Count 属性,那么这时候并不会爆出底层的异常,而是会给出完全不一致的结果。如果给出底层任意代码的运行异常,就是线程不安全的。反之就是线程安全的。 比如说 List<T>中原本有1个数据,被另外一个子线程给删除掉了,但是当前线程与之并发地去读取Count属性的时候可能仍然得到1返回值,可是当你随后用 lst[0] 这个办法去取得其第一个位置的数据时就会抛出程序运行异常。但是这丝毫不影响 List<T>“是线程安全的”这个性质。List<T>是线程安全的,它也完全不用为你的线程同步操作负责。多线程数据同步跟“线程安全的”完全不是同一个意思。 同样地,假设你不对 herolist 进行 lock 保护而使得你的查询结果出错、甚至程序崩溃,跟“linq是否是线程安全的”无关。这完全是你的程序同步问题,而不是线程安全问题。
刘欣的博客 2015-05-02
  • 打赏
  • 举报
回复
因为我没时间去搞清楚也不知道LINQ的SELECT里面做了什么,所以我怀疑了这个方法的多线程安全。 我就是问的只查询这种情况。 在保证这个时间片中,只有SELECT方式的前提下, 如果只用SELECT查询数据时,在多线程里面是安全的,那就再好不过了,谢谢各位帮帮忙。
  • 打赏
  • 举报
回复
如果其它线程(的执行的过程)可能修改它,那么当然需要 lock。 但是,这跟“linq 是不是线程安全的”没有任何关系。
moonwrite 2015-05-02
  • 打赏
  • 举报
回复
我以前也用过全局变量用来缓存一些数据 因为每个web请求都是一个线程 所以是多线程 有时候会出现一个问题 就是一个线程add数据 另外一个线程select 会报错 所以我就lock了
  • 打赏
  • 举报
回复
从没听过问方法是不是线程安全的…… 如果你仅仅只是查询的话,肯定是安全的 如果你的herolist还包含了其它变更操作,那就是不安全的

8,497

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 LINQ
社区管理员
  • LINQ
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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