带LINQ查询的C#锁

带LINQ查询的C#锁,c#,.net,linq,synchronization,thread-safety,C#,.net,Linq,Synchronization,Thread Safety,是否有必要按如下方式锁定LINQ语句?如果省略锁,那么当多个线程同时执行锁时,任何异常都将被抵消 lock (syncKey) { return (from keyValue in dictionary where keyValue.Key > versionNumber select keyValue.Value).ToList(); } PS:Writer线程确实存在,可以对字典进行变异。如果您的字典是静态的,而您运行查询的方法

是否有必要按如下方式锁定LINQ语句?如果省略锁,那么当多个线程同时执行锁时,任何异常都将被抵消

lock (syncKey)
{
    return (from keyValue in dictionary
            where keyValue.Key > versionNumber
            select keyValue.Value).ToList();
}

PS:Writer线程确实存在,可以对字典进行变异。

如果您的字典是静态的,而您运行查询的方法不是静态的(或其他并发访问场景),并且可以从其他线程修改字典,则是的,否则需要锁定-不是。

只要查询没有副作用(例如任何调用进行更改的代码的表达式)不需要锁定LINQ语句

基本上,如果您不修改数据(并且没有其他内容修改您正在使用的数据),那么您就不需要锁

如果您使用的是.NET4.0,并且有一个ConcurrentDictionary是线程安全的(当然不是在LINQ语句中)

更新

如果您正在修改数据,则需要使用锁。如果两个或多个线程尝试访问锁定的代码段,则会有一个小的性能损失,因为一个或多个线程等待释放锁。注意:如果您过度锁定,则可能会导致比刚使用se构建代码时性能更差的性能从一开始就是连续算法

如果您只读取数据,则不需要锁,因为没有可变的共享状态需要保护

如果不使用锁,则可能会出现间歇性错误,其中数据不完全正确,或者在读写器之间发生冲突时引发异常。根据我的经验,大多数情况下,您可能永远不会得到异常,您只会得到损坏的数据(除非您不一定知道它已损坏).这是另一个例子


从一开始就考虑在并行系统中开发的约束,有时你可以从系统中得到最好的效果。有时你可以重新编写代码,这样它就不用共享数据。有时你可以将数据分割成块,并使每个线程/任务在其自己的块上工作,然后在结束缝合时有一些进程将它们重新组合在一起。ain。

是的,在多线程场景中使用LINQ时,您需要锁定共享资源(编辑:当然,如果您的源代码集如Marc所说正在被修改,如果您只是在阅读它,您不必担心它)。如果您使用的是.Net 4或3.5的并行扩展,您可以考虑用ConcurrentDictionary替换字典(或使用其他自定义实现)。

大多数类型都是线程安全的,但在变异期间不是线程安全的

如果没有一个线程正在更改字典,那么您不需要做任何事情——只需阅读即可

如果一个线程正在改变它,那么你就有问题,需要同步。最简单的方法是<代码>锁,但是即使没有作者也会阻止并发的读者。如果有一个很好的机会,你会有更多的读者,作者,考虑使用<代码> Read RealSerkSimulm 同步。这将允许任意数量的读卡器(没有编写器),或:一个编写器


4,你也可以考虑一个

它不必是静态的——只是从多个线程访问的。最后,在迭代集合时需要锁定,而不是在这里返回。不,在多线程场景中不需要锁定字典。只有在多线程场景中修改数据时才需要锁定。如果所有线程都只读取字典,那么没有锁定一切都可以。这是eems你在我编辑后发表了评论。我知道从大多数收藏中阅读是线程安全的,一开始只是一个疏忽。嗨,马克,如果一个读者线程被一个作者打断,或者相反,会不会出现任何例外?@Ricky:不会被打断,另一个线程会阻塞(等等)@Ricky-为了证实@zespri的评论-作者将被阻止,直到读者全部完成;作者是排他性的!我的实际问题是没有大括号。谢谢。嗨,科林,如果读者线程被作者打断,或者相反,会出现任何例外吗?你所说的“中断”是什么意思?你的意思是:如果某个东西写而另一个东西读呢?如果是,那么结果是未定义的。它可能会中断。它可能不会中断。它可能会导致数据不一致。这实际上取决于写入程序获得控制的确切点。多线程是非确定性/间歇性错误的最大来源之一。如果你有读卡器和写入程序然后使用锁…或重新构造,这样你就不会同时拥有读写器。你的答案是:它可能会中断。你是说会抛出异常吗?谢谢。是的,或者可能不会。这就是野兽的不确定性。它可能会因引发异常而明显中断,或者很微妙,你没有注意到你直到很久以后。如果您有读卡器和写卡器,则使用锁,并因安全而遭受较小的性能损失。如果您只有读卡器,则不使用锁,并充分利用多核/处理器能力。