简体   繁体   English

泛型和对集合的锁定

[英]Generics and locking on collections

is there any difference between: 之间有什么区别?

lock((IDictionary) _collection).SyncRoot)

or 要么

lock(_collection)

Yes, the Monitor is take out on a different object in each, so the two are not functional equivalents. 是的,监控器在每个对象中都位于不同的对象上,因此两者不是等效的功能。 The SyncRoot is exposed so you can lock on it for collection member access (and the collection internally uses the same for locking). SyncRoot是公开的,因此您可以对其进行锁定以供集合成员访问(并且集合内部将其用于锁定)。 This allows code in the collection and code external to it to agree upon a specific lock object. 这允许集合中的代码及其外部的代码就特定的锁定对象达成共识。

I believe there are two questions. 我相信有两个问题。

Is it the same? 一样吗

The answer to this is "it depends." 答案是“视情况而定”。 It is only the same if SyncRoot is implemented by returing "this". 如果通过重播“ this”实现SyncRoot,则只有相同。 IDictionary is an interface and there is no contract detailing what object should be returned for the SyncRoot property. IDictionary是一个接口,没有合同规定应为SyncRoot属性返回什么对象。 The implementor is free to return "this" or a completely different object (IDictionary<TKey,TValue> does this). 实现者可以自由返回“ this”或完全不同的对象(IDictionary <TKey,TValue>执行此操作)。

Is it a good idea? 这是个好主意吗?

No. IDictionary implementors tend to return a different object (all of the standard collection clasess do). 不。理想主义者会趋向于返回一个不同的对象(所有标准收集类都这样做)。 So the odds are against you in creating a valid locking construct. 因此,在创建有效的锁定结构时,您很不利。

You should use a native Thread Safe Dictionary implementation instead of locking the entire Dictionary. 您应该使用本机线程安全字典实现,而不是锁定整个字典。

http://devplanet.com/blogs/brianr/archive/2008/09/26/thread-safe-dictionary-in-net.aspx http://devplanet.com/blogs/brianr/archive/2008/09/26/thread-safe-dictionary-in-net.aspx

That depends on the implementation of the IDictionary. 这取决于IDictionary的实现。 If the dictionary returns " this " as the SyncRoot , the statements are equivalent. 如果字典返回“ this ”作为SyncRoot ,则这些语句是等效的。

It's really easy to see how it is not the same: 很容易看出它们之间的不同之处:

Monitor.Enter((IDictionary) _collection).SyncRoot));
Monitor.Exit(_collection);

This will probably throw an exception saying the object is not the same. 这可能会引发异常,说明对象不相同。

I would recommend using the SyncRoot object. 我建议使用SyncRoot对象。 The IDictionary may simply return this and it will effectively be the same, but that's not guaranteed. IDictionary可以简单地返回this ,并且实际上是相同的,但是不能保证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM