部分线程安全的词典 [英] Partially thread-safe dictionary
问题描述
我已经有一个维护私人词典
实例缓存一些数据的类。
I have a class that maintains a private Dictionary
instance that caches some data.
类写入到从多个线程词典使用 ReaderWriterLockSlim
。
The class writes to the dictionary from multiple threads using a ReaderWriterLockSlim
.
我要揭露类的外部字典的值。
什么是这样做的一个线程安全的方式?
I want to expose the dictionary's values outside the class.
What is a thread-safe way of doing that?
现在,我有以下几点:
public ReadOnlyCollection<MyClass> Values() {
using (sync.ReadLock())
return new ReadOnlyCollection<MyClass>(cache.Values.ToArray());
}
有没有办法做到这一点不复制采集多少次?
Is there a way to do this without copying the collection many times?
我使用.net 3.5(而不是4.0)
I'm using .Net 3.5 (not 4.0)
推荐答案
修改:我个人认为以下code在技术上正确回答你的问题(如,它提供了一种方法来枚举集合中的值,而无需创建副本)。一些开发商更著名的比我强烈建议对这种做法,原因在他们编辑/评论他们解释。简而言之:这显然是一个坏主意所以我离开了答案,但建议您不要使用它
EDIT: I personally believe the below code is technically answering your question correctly (as in, it provides a way to enumerate over the values in a collection without creating a copy). Some developers far more reputable than I strongly advise against this approach, for reasons they have explained in their edits/comments. In short: This is apparently a bad idea. Therefore I'm leaving the answer but suggesting you not use it.
除非我失去了一些东西,我相信你会暴露你的价值观为的IEnumerable&LT; MyClass的&GT;
,而无需通过复制值产量
关键字:
Unless I'm missing something, I believe you could expose your values as an IEnumerable<MyClass>
without needing to copy values by using the yield
keyword:
public IEnumerable<MyClass> Values {
get {
using (sync.ReadLock()) {
foreach (MyClass value in cache.Values)
yield return value;
}
}
}
请注意,但是,(我猜你已经知道这一点),这种方法提供的懒惰的评价,这意味着值
财产上面可以实现的不可以被视为提供的快照的。
Be aware, however (and I'm guessing you already knew this), that this approach provides lazy evaluation, which means that the Values
property as implemented above can not be treated as providing a snapshot.
在换句话说......好吧,看看这个code(我当然在猜测一些此类的你的详细信息):
In other words... well, take a look at this code (I am of course guessing as to some of the details of this class of yours):
var d = new ThreadSafeDictionary<string, string>();
// d is empty right now
IEnumerable<string> values = d.Values;
d.Add("someKey", "someValue");
// if values were a snapshot, this would output nothing...
// but in FACT, since it is lazily evaluated, it will now have
// what is CURRENTLY in d.Values ("someValue")
foreach (string s in values) {
Console.WriteLine(s);
}
所以,如果这是一个要求,即该值
属性等同于一个的快照的什么是缓存
的属性被访问的时候,那么你将不得不作出一个副本。
So if it's a requirement that this Values
property be equivalent to a snapshot of what is in cache
at the time the property is accessed, then you're going to have to make a copy.
(开始280Z28):下面是如何的人不熟悉C#的方式做事可以锁定code的例子:
(begin 280Z28): The following is an example of how someone unfamiliar with the "C# way of doing things" could lock the code:
IEnumerator enumerator = obj.Values.GetEnumerator();
MyClass first = null;
if (enumerator.MoveNext())
first = enumerator.Current;
(结束280Z28)
(end 280Z28)
这篇关于部分线程安全的词典的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!