Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从多个线程在字典中添加新项_C#_Multithreading_Dictionary_Concurrency - Fatal编程技术网

C# 从多个线程在字典中添加新项

C# 从多个线程在字典中添加新项,c#,multithreading,dictionary,concurrency,C#,Multithreading,Dictionary,Concurrency,在从多个线程使用静态字典时,向静态字典添加新项时遇到问题。知道我哪里做错了吗? 正在初始化字典: public static class Server { public static volatile Dictionary<int, List<SomeClass>> Values; } 公共静态类服务器 { 公共静态可变字典值; } 正在尝试添加项目: Server.Values.Add(someInt, new List<SomeClass> {

在从多个线程使用静态字典时,向静态字典添加新项时遇到问题。知道我哪里做错了吗? 正在初始化字典:

public static class Server
{
    public static volatile Dictionary<int, List<SomeClass>> Values;
}
公共静态类服务器
{
公共静态可变字典值;
}
正在尝试添加项目:

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

正如Jon Skeet所解释的,您使用的对象不能保证线程安全

尝试使用针对多线程并发场景而设计的

public static class Server
{
    public static  ConcurrentDictionary<int, List<SomeClass>> Values =
                      new ConcurrentDictionary<int, List<SomeClass>>(); 
}
公共静态类服务器
{
公共静态ConcurrentDictionary值=
新的ConcurrentDictionary();
}
这里是如何使用它

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

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

private object _lock = new object();
然后围绕访问共享资源的任何代码,如下所示:

lock(_lock)
{
    // perform operations on shared resource here.
}
需要注意的是,您应该为每个共享资源使用不同的锁,而不是为所有资源使用一个锁。如果将锁对象与多个资源一起使用,代码可能会非常低效。如果一个线程抓住了锁以便可以使用资源A,那么其他线程将不得不等待释放锁,即使它们想要访问与资源A无关的资源B。因此,最好每个资源有一个锁对象,并命名锁对象,这样您就知道应该使用哪些资源


另一种替代方法(如BRAHIM Kamel的回答所示)是使用一个替代品(如果可用的话),替代已经烘焙了线程同步的共享资源,如
ConcurrentDictionary
。虽然这在您的情况下可能不可行。

是的,您使用的类型被证明是线程不安全的,来自多个线程,没有任何安全措施。我想我可能会猜测,但是你为什么不告诉我们问题是什么,而不是让我们猜测呢?错误是什么?这就是问题-工作室没有给出错误-它只是打破了良好的“打破”如果您有concurrentDictionary,为什么要重新启用weel:p这是值得一提的,以防他无法更改+1的类型。我更喜欢变量
ServerDictionaryLock
,那么很明显您用它锁定了什么。@TimSchmelter--我已经尽力使它尽可能通用,但是我明白你的意思。@rory.ap:lock对象的问题是人们以这种方式实现它,它建议每个类使用一个锁变量。这将锁定整个实例以及使用它的任何操作。@TimSchmelter说得好,我忘了添加它。这是一个时间约束。在这种情况下,added=false和Server.Values=null。这是我得到的最大的“错误”你必须先初始化它我更新了我的答案