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”时,所有引用都会显示更改。
我会尽量恢复一切:
我有一个 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”时,所有引用都会显示更改。