C# Dictionary<int,Object> 自行更新

C# Dictionary<int,Object> updates by itself

我会尽量恢复一切:

我有一个 class 可以创建一个字典(我们称之为辅助字典),其中包含另一个字典的某些元素的初始值,(为简单起见,我们称之为主字典和这个 class 只做一次)然后一个线程每 x 毫秒检查一次主字典,每 y 毫秒定期更新一次,以查找在初始化阶段存储的元素的任何更改。

我的问题是,当我想比较主词典中 element1 的值与辅助词典中 element1 的值时,它们总是相同的,(我理解,直到主词典是nnot 更新,两个值将相同,但是当主字典更新时,第二个字典也会立即更新,我什么都不做)

我试过 ConcurrentDictionaries,使用锁,两者的结合,在初始化函数中创建一个新元素而不是直接传递它,但似乎没有任何效果

class Checker
{
    private static bool secondaryDictionaryHasChanged = false;
    private static ConcurrentDictionary<int, ValueDTO> secondaryDictionary = new ConcurrentDictionary<int, ValueDTO>();

    public Checker()
    {
        initSecondaryDictionary();

        Thread checkChangedValsThread = new Thread(() => checkChangedValsThreadFunction(1000));
        checkChangedValsThread.Start();
    }

    public void initSecondaryDictionary()
    {
        Object MainLock = new Object();
        lock (MainLock)
        {
            Object secondaryLock = new Object();
            lock (secondaryLock)
            {
                foreach (var variable in Maindictionary)
                {
                    if (variable.isElegibleValue)
                    {
                        ValueDTO ValueDTOToAdd = new ValueDTO();
                        ValueDTOToAdd.EligibleVar = variable;

                        if (variable.contextVariables.Count > 0)
                        {
                            List<Var> contextVariablesToAdd = new List<Var>();
                            foreach (var item in variable.contextVariables)
                            {
                                contextVariablesToAdd.Add(getVarFromMainDictionary(item));
                            }
                            ValueDTOToAdd.ContextVars = contextVariablesToAdd;
                        }
                        secondaryDictionary.TryAdd(ValueDTOToAdd.EligibleVar.varCode, ValueDTOToAdd);
                    }
                }
            }
        }
        secondaryDictionaryHasChanged = false;
    }

    public void checkChangedValsThreadFunction(int checkTime)
    {
        while (true)
        {
            try
            {
                if (!secondaryDictionaryHasChanged)
                {
                    Thread.Sleep(checkTime);

                    Object mainLock = new Object();
                    lock (mainLock)
                    {
                        Object secondaryLock = new Object();
                        lock (secondaryLock)
                        {
                            foreach (var item in secondaryDictionary)
                            {
                                ValueDTO secondaryDictionaryDTO = item.Value;
                                Var variableInSecondary = secondaryDictionaryDTO.EligibleVar;

                                Var variableInMain = getVarFromMainDictionary(item.Value.EligibleVar.varID);

                                int valueInMain = variableInMain.getIntValue();
                                int valueInSecondary = variableInSecondary.getIntValue();

                                if (valueInMain != valueInSecondary)
                                {
                                    //IT NEVER ENTERS THIS HERE
                                }

                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("Some exception: " + e.Message);
            }
        }
    }
}

internal class ValueDTO
{
    public Var EligibleVar { get; set; }
    public List<Var> ContextVars { get; set; }
}

internal class Var
{
    public int varCode { get; set; }
    public string varID { get; set; }

}

我添加了代码的缩减版本 我有问题是它永远不会进入 if(mainValue != secondaryValue)

任何有关我哪里出错的帮助或信息将不胜感激

正如fildor 已经说过的,您有一个对象和两个对它的引用。 为了简化您的问题,我创建了一个简短示例:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class Example
{
    class Person
    {
        public string Name
        {
            get;
            set;
        }
    }

    public static void Main()
    {
        var myPerson = new Person();
        myPerson.Name = "User1";
        var list1 = new List<Person>();
        var list2 = new List<Person>();
        // put a reference to myPerson into each of the lists
        list1.Add(myPerson);
        list2.Add(myPerson);
        // get the reference to myPerson from list1
        var myPersonInList1 = list1[0]
        myPersonInList1.Name = "User2";
        // this will print User2 because there is only one person object         
        Console.WriteLine(list2[0].Name);
    }
}

基本上无论你在哪里传递Person,它总是对你创建的Person实例的引用。对它的所有更改都将应用于引用后面的对象。所有引用都指向同一个对象。

更深入的知识非常简单,但我希望你能明白要点: 有一个堆栈和一个堆存储。堆栈包含值类型和引用,堆包含对象。

堆栈:

Variable | Value

--------------------
myPerson | @abc123
list1[0] | @abc123
list2[0] | @abc123
myInt    | 42

堆:

Address  | Value
-------------------
abc123   | { Name: "User2" }

现在每次创建指向 myPerson 的变量时,您只在堆栈中创建一个指向堆中同一对象的新条目。现在,当然,当您更新引用后面的对象并将其名称设置为“User1”时,所有引用都会显示更改。