我在从多个线程使用它时向静态字典添加新项目时遇到问题。我做错了什么想法? 初始化字典:
public static class Server
{
public static volatile Dictionary<int, List<SomeClass>> Values;
}
尝试添加项目:
Server.Values.Add(someInt, new List<SomeClass> { elements});
答案 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
。虽然在你的情况下这可能不可行。