Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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_.net Core - Fatal编程技术网

C# 只初始化字典中的值一次,然后更新

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

我目前正在跟踪在托架之间移动的包,这些更改大约每十几秒发生一次,所以我有几个线程访问一些字典。这个想法是,在前几次,我将不会有lastBay值(程序刚刚启动),但当
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);
    }
}