【问题标题】:Thread Safety with Dictionary字典的线程安全
【发布时间】:2011-11-18 13:12:27
【问题描述】:

如果我有一个

Dictionary<int, StreamReader> myDic = new Dictionary<int, StreamReader>
//Populate dictionary

一个线程做

myDic[0] = new StreamReader(path);

另一个线程做

myDic[1] = new StreamReader(otherpath)

这个线程安全吗,因为字典中被修改的实际项目与另一个线程上的不同,或者我会得到一个InvalidOperationException: Collection was modified

【问题讨论】:

    标签: c# .net multithreading .net-4.0


    【解决方案1】:

    如果您在修改时枚举字典,您只会得到InvalidOperationException: Collection was modified

    但是,这不是线程安全的。
    如果其中一项操作导致字典调整大小,则另一项可能会丢失。
    请改用ConcurrentDictionary

    【讨论】:

    • , 如果我有 cuncorrentDictionary 并且我需要检查 containsKey 然后如果为真则执行某些操作:那么我仍然必须锁定它:` lock (locker) { if (MyConDic.ContainsKey(toUserName )) {...}}`....不是吗?
    • @RoyiNamir:这违背了ConcurrentDictionary 的全部目的。使用其 API
    • 但是谁保证在第 96 行不会有另一个线程会添加输入?i.stack.imgur.com/MwDuU.jpg?请详细说明
    • 是的;不要那样做。相反,请使用 GetOrAdd() 之类的原子 API。请参阅文档。
    • 我从来没有遇到过并行使用赋值运算符的问题(事实上,这正是.ToDictionary() 可能会做的事情。我根据您在此处的回答提出了一个澄清问题:stackoverflow.com/questions/28749065/…
    【解决方案2】:

    System.Collections.Generic 集合仅在从多个线程读取时才是线程安全的。

    引用自 MSDN

    System.Collections.Generic 集合类不提供任何线程同步;当在多个线程上同时添加或删除项目时,用户代码必须提供所有同步

    如果您希望读写操作的线程安全,请考虑使用System.Collections.Concurrent

    *当您编写新代码时,只要集合将同时写入多个线程,请使用并发集合类。 *

    【讨论】:

      【解决方案3】:

      要改进您的代码,您可能需要查找 ConcurrentDictionary 类。它将解决多线程的一些问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-20
        • 2011-01-17
        • 2010-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多