加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 部分线程安全的字典

发布时间:2020-12-15 23:54:27 所属栏目:百科 来源:网络整理
导读:我有一个类维护一个缓存一些数据的私有Dictionary实例. 该类使用ReaderWriterLockSlim从多个线程写入字典. 我想在课外公开字典的值. 什么是线程安全的方法呢? 现在,我有以下内容: public ReadOnlyCollectionMyClass Values() { using (sync.ReadLock()) re
我有一个类维护一个缓存一些数据的私有Dictionary实例.

该类使用ReaderWriterLockSlim从多个线程写入字典.

我想在课外公开字典的值.
什么是线程安全的方法呢?

现在,我有以下内容:

public ReadOnlyCollection<MyClass> Values() {
    using (sync.ReadLock())
        return new ReadOnlyCollection<MyClass>(cache.Values.ToArray()); 
}

有没有办法这样做而不需要多次复制集合?

我正在使用.Net 3.5(不是4.0)

解决方法

编辑:我个人认为下面的代码在技术上正确地回答了你的问题(因为,它提供了一种枚举集合中的值而无需创建副本的方法).由于他们在编辑/评论中已经解释过的原因,一些开发人员比我强烈建议反对这种方法更有信誉.简而言之:这显然是一个坏主意.因此,我将离开答案,但建议你不要使用它.

除非我遗漏了某些内容,否则我相信您可以将您的值公开为IEnumerable< MyClass>无需使用yield关键字复制值:

public IEnumerable<MyClass> Values {
    get {
        using (sync.ReadLock()) {
            foreach (MyClass value in cache.Values)
                yield return value;
        }
    }
}

但是请注意(我猜你已经知道这一点),这种方法提供了惰性求值,这意味着上面实现的Values属性不能被视为提供快照.

换句话说……好吧,看看这段代码(我当然会猜测你这类的一些细节):

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);
}

因此,如果要求此Values属性等同于访问该属性时缓存中的内容的快照,那么您将不得不进行复制.

(开始280Z28):以下是一个不熟悉“C#做事方式”的人如何锁定代码的例子:

IEnumerator enumerator = obj.Values.GetEnumerator();
MyClass first = null;
if (enumerator.MoveNext())
    first = enumerator.Current;

(结束280Z28)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读