在多个线程的字典中添加新项

时间:2016-09-29 11:55:30

标签: c# multithreading dictionary concurrency

我在从多个线程使用它时向静态字典添加新项目时遇到问题。我做错了什么想法? 初始化字典:

public static class Server
{
    public static volatile Dictionary<int, List<SomeClass>> Values;
}

尝试添加项目:

Server.Values.Add(someInt, new List<SomeClass> { elements});

2 个答案:

答案 0 :(得分:10)

正如Jon Skeet所解释的那样,您正在使用一个不保证是线程安全的对象

尝试使用专为具有多线程的并发场景设计的ConcurrentDictionary

public static class Server
{
    public static  ConcurrentDictionary<int, List<SomeClass>> Values =
                      new ConcurrentDictionary<int, List<SomeClass>>(); 
}

这里如何使用

bool added = Server.Values.TryAdd(someInt, new List<SomeClass> { elements});

答案 1 :(得分:3)

通常,在处理多个线程之间共享的资源时,需要使用同步机制(如lock())来使代码线程安全。创建一个用作锁的公共对象:

private object _lock = new object();

然后围绕访问共享资源的任何代码,如下所示:

lock(_lock)
{
    // perform operations on shared resource here.
}

请务必注意,您应该为每个共享资源设置一个不同的锁,而不是一个用于所有资源的锁。如果您使用具有多个资源的锁定对象,则代码可能效率非常低。如果一个线程抓取锁定以便它可以使用资源A,那么即使他们想要访问与资源A无关的资源B,其他线程也必须等待锁定被释放。因此,最好有每个资源一个锁定对象,并命名您的锁定对象,以便您知道它们应该与哪些资源一起使用。

另一种选择(正如BRAHIM Kamel的答案所示)是使用已替换线程同步的共享资源(如果可用),如ConcurrentDictionary。虽然在你的情况下这可能不可行。