C# 如何在ConcurrentDictionary中添加项目<;字符串,IList<;对象>&燃气轮机;

C# 如何在ConcurrentDictionary中添加项目<;字符串,IList<;对象>&燃气轮机;,c#,concurrentdictionary,C#,Concurrentdictionary,我有一个concurrentdictionary>Let say object as Artifact 我想添加一个新对象。对象通常包含键列表,我有一个函数来获取这些键 如果密钥不存在,我知道如何添加到字典中,但是如果密钥已经存在,我不确定如何更新列表。任何帮助都将不胜感激 public bool AddToken(Artifact artifact) { IList<string> terms = GetTerms(artifact);

我有一个concurrentdictionary>Let say object as Artifact

我想添加一个新对象。对象通常包含键列表,我有一个函数来获取这些键

如果密钥不存在,我知道如何添加到字典中,但是如果密钥已经存在,我不确定如何更新列表。任何帮助都将不胜感激

public bool AddToken(Artifact artifact)
        {
            IList<string> terms = GetTerms(artifact);
            foreach(var term in terms)
            {
                if (ExistsTerm(term))
                {
                    termDictionary.AddOrUpdate(??)
                }else
                {
                    IList<Artifact> a = new List<Artifact>();
                    a.Add(artifact); 
                    termDictionary.TryAdd(term, artifact);
                }

            }
            return true;
        }
public bool AddToken(工件工件)
{
IList terms=GetTerms(工件);
foreach(var术语)
{
if(现有(期限))
{
termDictionary.AddOrUpdate(?)
}否则
{
IList a=新列表();
a、 添加(工件);
TryAdd(术语,工件);
}
}
返回true;
}

试试
术语词典[]=
。这将同时进行添加和更新(并且它将防止重复的密钥异常(冒着覆盖现有数据的风险)。

尝试
termDictionary[]=
。这将同时进行添加和更新(并且它将防止重复的密钥异常(冒着覆盖现有数据的风险).

ConcurrentDictionary获取或添加方法获取工厂委托:

var list = termDictionary.GetOrAdd(term, t=>new List<Artifact>());
list.Add(artifact);
var list=termDictionary.GetOrAdd(term,t=>newlist());
添加(工件);

ConcurrentDictionary获取或添加方法获取工厂委托:

var list = termDictionary.GetOrAdd(term, t=>new List<Artifact>());
list.Add(artifact);
var list=termdedictionary.GetOrAdd(term,t=>newlist());
添加(工件);
您可以使用

从概念上讲,AddOrUpdate方法将始终导致集合中的值更改

这些方法的要点是解决并发系统中的时间性质问题。对于多线程,您无法预测在任何执行点的集合中会发现哪些元素

下面是MSDN示例

class CD_GetOrAddOrUpdate
{
    // Demonstrates:
    //      ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
    //      ConcurrentDictionary<TKey, TValue>.GetOrAdd()
    //      ConcurrentDictionary<TKey, TValue>[]
    static void Main()
    {
        // Construct a ConcurrentDictionary
        ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>();

        // Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
        Parallel.For(0, 10000, i =>
        {
            // Initial call will set cd[1] = 1.  
            // Ensuing calls will set cd[1] = cd[1] + 1
            cd.AddOrUpdate(1, 1, (key, oldValue) => oldValue + 1);
        });

        Console.WriteLine("After 10000 AddOrUpdates, cd[1] = {0}, should be 10000", cd[1]);

        // Should return 100, as key 2 is not yet in the dictionary
        int value = cd.GetOrAdd(2, (key) => 100);
        Console.WriteLine("After initial GetOrAdd, cd[2] = {0} (should be 100)", value);

        // Should return 100, as key 2 is already set to that value
        value = cd.GetOrAdd(2, 10000);
        Console.WriteLine("After second GetOrAdd, cd[2] = {0} (should be 100)", value);
    }
}
class CD\u GetOrAddOrUpdate
{
//表明:
//ConcurrentDictionary.AddOrUpdate()
//ConcurrentDictionary.GetOrAdd()
//ConcurrentDictionary[]
静态void Main()
{
//构造一个ConcurrentDictionary
ConcurrentDictionary cd=新建ConcurrentDictionary();
//用10000个相互竞争的addor更新轰炸ConcurrentDictionary
对于(0,10000,i=>
{
//初始调用将设置cd[1]=1。
//随后的呼叫将设置cd[1]=cd[1]+1
cd.AddOrUpdate(1,1,(键,oldValue)=>oldValue+1);
});
WriteLine(“在10000个AddOrUpdates之后,cd[1]={0},应该是10000”,cd[1]);
//应返回100,因为键2尚未在字典中
int值=cd.GetOrAdd(2,(键)=>100);
WriteLine(“在初始GetOrAdd之后,cd[2]={0}(应该是100)”,值);
//应返回100,因为键2已设置为该值
值=cd.GetOrAdd(210000);
WriteLine(“在第二个GetOrAdd之后,cd[2]={0}(应该是100)”,值);
}
}
您可以使用

从概念上讲,AddOrUpdate方法将始终导致集合中的值更改

这些方法的要点是解决并发系统中的时间性质问题。对于多线程,您无法预测在任何执行点的集合中会发现哪些元素

下面是MSDN示例

class CD_GetOrAddOrUpdate
{
    // Demonstrates:
    //      ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
    //      ConcurrentDictionary<TKey, TValue>.GetOrAdd()
    //      ConcurrentDictionary<TKey, TValue>[]
    static void Main()
    {
        // Construct a ConcurrentDictionary
        ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>();

        // Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
        Parallel.For(0, 10000, i =>
        {
            // Initial call will set cd[1] = 1.  
            // Ensuing calls will set cd[1] = cd[1] + 1
            cd.AddOrUpdate(1, 1, (key, oldValue) => oldValue + 1);
        });

        Console.WriteLine("After 10000 AddOrUpdates, cd[1] = {0}, should be 10000", cd[1]);

        // Should return 100, as key 2 is not yet in the dictionary
        int value = cd.GetOrAdd(2, (key) => 100);
        Console.WriteLine("After initial GetOrAdd, cd[2] = {0} (should be 100)", value);

        // Should return 100, as key 2 is already set to that value
        value = cd.GetOrAdd(2, 10000);
        Console.WriteLine("After second GetOrAdd, cd[2] = {0} (should be 100)", value);
    }
}
class CD\u GetOrAddOrUpdate
{
//表明:
//ConcurrentDictionary.AddOrUpdate()
//ConcurrentDictionary.GetOrAdd()
//ConcurrentDictionary[]
静态void Main()
{
//构造一个ConcurrentDictionary
ConcurrentDictionary cd=新建ConcurrentDictionary();
//用10000个相互竞争的addor更新轰炸ConcurrentDictionary
对于(0,10000,i=>
{
//初始调用将设置cd[1]=1。
//随后的呼叫将设置cd[1]=cd[1]+1
cd.AddOrUpdate(1,1,(键,oldValue)=>oldValue+1);
});
WriteLine(“在10000个AddOrUpdates之后,cd[1]={0},应该是10000”,cd[1]);
//应返回100,因为键2尚未在字典中
int值=cd.GetOrAdd(2,(键)=>100);
WriteLine(“在初始GetOrAdd之后,cd[2]={0}(应该是100)”,值);
//应返回100,因为键2已设置为该值
值=cd.GetOrAdd(210000);
WriteLine(“在第二个GetOrAdd之后,cd[2]={0}(应该是100)”,值);
}
}

是否有多个线程正在更新此字典?还是只有一个线程在更新?我想只有一个线程,然后您会得到
var dictArtifactList=termDictionary[];
作为列表。您需要一种方法来比较当前工件与列表中的工件。我的首选方法是使用LINQ查询并执行
dictArtifactList.FirstOrDefault();
然后更新列表中的工件。@mmushtaq我检查了链接,它不完全相同,但我从中得到了想法。我检查我的术语[键].contains(artifact),如果不是,我就添加它。ConcurrentDictionary与Dictionary有一组完全不同的方法;根本不是该链接问题的副本。多个线程会更新该字典吗?还是只有一个线程在更新?我想只有一个线程,然后您会得到
var dictArtifactList=termDictionary[];
作为列表。您需要一种方法来比较当前工件与列表中的工件。我的首选方法是使用LINQ查询并执行
dictArtifactList.FirstOrDefault();
然后更新列表中的工件。@mmushtaq我检查了链接,它不完全相同,但我从中得到了想法。我检查我的术语[键].contains(artifact),如果不是,我就添加它。ConcurrentDictionary与Dictionary有一组完全不同的方法;完全不是该l的副本