部分线程安全的词典 [英] Partially thread-safe dictionary

查看:122
本文介绍了部分线程安全的词典的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经有一个维护私人词典实例缓存一些数据的类。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆