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

vla*_*lad 2 c# concurrency multithreading dictionary

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

public static class Server
{
    public static volatile Dictionary<int, List<SomeClass>> Values;
}
Run Code Online (Sandbox Code Playgroud)

试图添加一个项目:

Server.Values.Add(someInt, new List<SomeClass> { elements});
Run Code Online (Sandbox Code Playgroud)

BRA*_*mel 10

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

尝试使用 ConcurrentDictionary哪个是为多线程的并发场景设计的

public static class Server
{
    public static  ConcurrentDictionary<int, List<SomeClass>> Values =
                      new ConcurrentDictionary<int, List<SomeClass>>(); 
}
Run Code Online (Sandbox Code Playgroud)

在这里如何使用它

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


ror*_*.ap 7

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

private object _lock = new object();
Run Code Online (Sandbox Code Playgroud)

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

lock(_lock)
{
    // perform operations on shared resource here.
}
Run Code Online (Sandbox Code Playgroud)

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

另一种方法(如 BRAHIM Kamel 的答案所示)是使用替代品(如果可用)来替换已经内置线程同步的共享资源,例如ConcurrentDictionary. 尽管这对于您的情况可能不可行。

  • 这是值得一提的,以防他无法更改类型+1 (2认同)