C# 只初始化字典中的值一次,然后更新
我目前正在跟踪在托架之间移动的包,这些更改大约每十几秒发生一次,所以我有几个线程访问一些字典。这个想法是,在前几次,我将不会有lastBay值(程序刚刚启动),但当C# 只初始化字典中的值一次,然后更新,c#,multithreading,dictionary,.net-core,C#,Multithreading,Dictionary,.net Core,我目前正在跟踪在托架之间移动的包,这些更改大约每十几秒发生一次,所以我有几个线程访问一些字典。这个想法是,在前几次,我将不会有lastBay值(程序刚刚启动),但当A==B第一次时,我保存A的值(打包机降落到的间隔,因此是它所在的最后一个间隔),然后每次A==B都更新所述值 private void in_bay() { String line_type = getDictionaryValues("global", "line_ty
A==B
第一次时,我保存A的值(打包机降落到的间隔,因此是它所在的最后一个间隔),然后每次A==B
都更新所述值
private void in_bay()
{
String line_type = getDictionaryValues("global", "line_type").getStringValue();
bool result = false;
switch (line_type)
{
case "A_1":
int A = getVariableFromBucket("A_Act").getIntValue();
int B = getVariableFromBucket("A_Next").getIntValue();
result = A == B ? true : false;
if (result)
{
setDictionaryValues("global", "lastBay", new Variable("UNSIGNED8") { binaryValue = Utils.intToByteArray(A) });
}
break;
}
setVariableInBucket("IN_BAY", BitConverter.GetBytes(result));
log("IN_BAY flag in BUCKET: " + getVariableFromBucket("IN_BAY").getBoolValue(), DEBUG);
if (getDictionaryValues("global", "lastBay").binaryValue != null)
{
log("lastBay value in global: " + getDictionaryValues("global", "lastBay").getIntValue(), DEBUG);
}
else
{
log("undefined bay",DEBUG);
}
}
我有一个getDictionaryValue()函数,返回变量(如果不在字典中,则返回一个空变量):
以及一个setDictionaryValue()函数,该函数实际设置所选字典的值:
public void setDictionaryValues(String DictionaryName, String VariableName, Variable VaValue)
{
try
{
lock (GlobalConstants.filtersLock)
{
if (!functionDictionary.ContainsKey(DictionaryName))
{
functionDictionary.Add(DictionaryName, new Dictionary<String, Variable>());
}
if (!functionDictionary[DictionaryName].ContainsKey(VariableName))
{
functionDictionary[DictionaryName].Add(VariableName, Value);
}
else
{
functionDictionary[DictionaryName][VariableName] = Value;
}
}
}
catch (Exception e)
{
log("An error has ocurred when setting values to functionDictionary: "+ e,DEBUG);
throw new Exception(e.ToString());
}
}
public void setDictionaryValue(字符串DictionaryName、字符串VariableName、变量VaValue)
{
尝试
{
锁(GlobalConstants.filtersLock)
{
if(!functionDictionary.ContainsKey(DictionaryName))
{
添加(DictionaryName,newdictionary());
}
如果(!functionDictionary[DictionaryName].ContainsKey(VariableName))
{
functionDictionary[DictionaryName]。添加(变量名称,值);
}
其他的
{
functionDictionary[DictionaryName][VariableName]=值;
}
}
}
捕获(例外e)
{
日志(“将值设置为functionDictionary时出现错误:“+e,调试”);
抛出新异常(例如ToString());
}
}
问题是,第一次A==B
时,它会正确记录接收到的值,但当值再次更改(包再次开始移动)时,代码不再显示lastBay的值,就好像字典全局不再有lastBay的值一样。我附上了一张图像,其中包含预期结果和获得的结果:
这里我缺少什么?从注释线程来看,问题似乎是在不同的对象实例上调用了
in_bay
,而functionDictionary
是一个非静态字段,因此每次都要处理不同的dictionary实例
我只是想借此机会指出,如果您只使用类和变量,而不是添加字典和“变量”对象作为抽象层,那么您的代码可能会简单得多
private void in_bay()
{
string? line_type = BayState.line_type;
bool result = false;
if(line_type == "A_1")
{
int A = Bucket.A_Act;
int B = Bucket.A_Next;
result = A == B;
if (result)
{
BayState.lastBay = A;
}
}
Bucket.IN_BAY = result;
log("IN_BAY flag in BUCKET: " + Bucket.IN_BAY, DEBUG);
if (BayState.lastBay != null)
{
log("lastBay value in global: " + BayState.lastBay.Value, DEBUG);
}
else
{
log("undefined bay", DEBUG);
}
}
我几乎可以保证任何“业务需要”推动了对词典的需求,这可以通过另一种方式来实现,它仍然允许您编写干净且不易出错的代码。问题出现了,为什么您不使用
ConcurrentDictionary
?您的开关只有一个大小写
:如果行类型
不是a\u 1怎么办
?尝试记录行类型,查看它是否始终为“A\u 1”。此外,作为一个通用指针,请学习使用调试器,以便逐行遍历代码并查看每个变量的值。我知道在多线程环境中这很难,但我怀疑您这里的问题可能会通过简单的单线程单元测试重现。(鉴于“bucket”和字典的所有键都是常量,对我来说,问题是您为什么要使用字典?@StriplingWarrior Bussiness need,我以前反对过,但解决方案已经全面实现了这些。我已经使用debug窗口冻结线程,并尝试单独使用一个线程,但即使这样,我也找不到错误。至于开关,如果我将其更改为一个非常全面的if-else语句,我仍然会得到相同的结果可能是,functionDictionary
在调用in_-bay
?也许这是一个私人领域,你的类有很多不同的实例?
private void in_bay()
{
string? line_type = BayState.line_type;
bool result = false;
if(line_type == "A_1")
{
int A = Bucket.A_Act;
int B = Bucket.A_Next;
result = A == B;
if (result)
{
BayState.lastBay = A;
}
}
Bucket.IN_BAY = result;
log("IN_BAY flag in BUCKET: " + Bucket.IN_BAY, DEBUG);
if (BayState.lastBay != null)
{
log("lastBay value in global: " + BayState.lastBay.Value, DEBUG);
}
else
{
log("undefined bay", DEBUG);
}
}