рекурсивный вызов в трассировке стека, но ничего в коде C # - PullRequest
0 голосов
/ 14 сентября 2018

Недавно я столкнулся с проблемой в приложении C # .Net. Неизмененная трассировка стека выглядит следующим образом:

2018-09-12 21:08:31,596 [] [112] ERROR PLoggerFactory::RunLogic - Exception : System.Exception: Serialisation errorSystem.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Block`2.GetConfigFromDB()
   at Block`2.GetConfigFromDB()
   at Block`2.Begin(IParcelGettable`1 P, Action`1 f)
   at Run.<>c__DisplayClass45_0.<RunInNewThread>b__1()

В приведенном выше примере GetConfigFromDB вызывается в стеке. Но я проверил код, в этом нет ничего рекурсивного GetConfigFromDB. Это возможно?

Пожалуйста, дайте мне знать, если требуется код GetConfigFromDB, я изменю его и поделюсь.

----- РЕДАКТИРОВАТЬ ------- Код добавлен

private Dictionary<string, object> GetConfigFromDB()
        {

            blockConfigJson = controller.BlockConfig.GetConfig(this.BlockInstanceId);
            if (String.IsNullOrEmpty(blockConfigJson))
            {
                return new Dictionary<string, object>();
            }
            Dictionary<string, object> configDictionary = new Dictionary<string, object>();
            try
            {
                configDictionary = JsonConvert.DeserializeObject<Dictionary<string, object>>(blockConfigJson);
                foreach (var v in configDictionary)
                {
                    var key = "__" + this.BlockInstanceId + "." + v.Key;
                    if (SharedConfig.ContainsKey(key))
                    {
                        SharedConfig[key] = v.Value;
                    }
                    else
                    {
                        SharedConfig.Add(key, v.Value);
                    }

                    if (v.Key.Trim() == "_extraInfo_")
                    {
                        dynamic extraInfo = JsonConvert.DeserializeObject(configDictionary["_extraInfo_"].ToString());
                        JsonConvert.DeserializeObject<List<Variable>>(extraInfo["Variables"].ToString());
                        Dictionary<string, string> _variablesTemp = new Dictionary<string, string>();
                        try
                        {
                            _variablesTemp = JsonConvert.DeserializeObject<Dictionary<string, string>>(extraInfo["Variables"].ToString());
                        }
                        catch (Exception ex)
                        {
                            mLogger.Debug("Variable parsing error " + ex);
                        }


                        List<Variable> _variables = new List<Variable>();
                        foreach (KeyValuePair<string, string> kyp in _variablesTemp)
                        {
                            _variables.Add(new Variable()
                            {
                                variableName = kyp.Key,
                                variableValue = kyp.Value
                            });
                        }

                        foreach (Variable _variable in _variables)
                        {
                            if (!SharedVariables.ContainsKey(_variable.variableName))
                            {
                                SharedVariables.Add(_variable.variableName, _variable.variableValue);
                                new Caching().Send(_variable.variableName, _EvaluateConfigValue(_variable.variableValue, this.blockConfig, this.SharedConfig, this.SharedVariables, this.propagatedConfig, this.propagatedVariables, this.ControlId));
                            }
                        }
                    }

                }
            }
            catch (Exception ex)
            {

                configDictionary = new Dictionary<string, object>();
                throw;
            }
            return configDictionary;
        }

1 Ответ

0 голосов
/ 14 сентября 2018

Эта трассировка стека показывает, что ваш метод вызывает Dictionary<,>.Insert(TKey, TValue, bool), но, конечно, вы никогда этого не сделаете. Вы не можете, потому что это закрытый метод, вызываемый Dictionary<,>.Add, который вы делаете вызываете.

Когда оптимизация включена, трассировка стека не всегда на 100% точна. Особенно, когда вызываются тривиальные методы, которые почти наверняка становятся встроенными. Dictionary<,>.Add такой тривиальный метод: он буквально ничего не делает, кроме как вызывает Dictionary<,>.Insert. Похоже, было восстановлено достаточно информации, чтобы определить, что между Dictionary<,>.Insert и GetConfigFromDB было что-то , но не то, что это может быть. Поскольку ничего лучшего нет, имя GetConfigFromDB используется во второй раз.

...