Как я могу сделать этот поток свойств c # безопасным? - PullRequest
0 голосов
/ 17 октября 2019

У меня есть следующий код в коде c #, который вычисляет значение свойства:

    public class Options
    {
        public bool UseFeature
        {
            public bool NoUseFeatureInternal { get; set; }
            public bool UseFeatureInternal { get; set; }
            get
            {
                // Command line param
                if (NoUseFeatureInternal )
                {
                    return false;
                }

                // Command line param
                if (UseFeatureInternal )
                {
                    return true;
                }

                if (cachedUseFeature.HasValue)
                {
                    return cachedUseFeature.Value;
                }

                string userName= Override.GetUserName();
                cachedUseFeature = ToolBox.Config.Flights.IsActive("FeatureName", overrideName);

                return cachedUseFeature.Value;
            }
        }

        private bool? cachedUseFeature;
    }

    public static class ToolBox
    {
        private static Lazy<GlobalConfig> configLazy = new Lazy<GlobalConfig>(() => GlobalConfig.Load() ?? GlobalConfig.Default);

        public static GlobalConfigConfig
        {
            get
            {
                return configLazy.Value;
            }
        }
    }

    public class GlobalConfig
    {
        public static GlobalConfig Load(string filePath = null)
        {
            filePath = filePath ?? GetGlobalConfigPath();

            if (string.IsNullOrWhiteSpace(filePath) || !File.Exists(filePath))
            {
                return null;
            }

            string fileContents = File.ReadAllText(filePath);

            // Parses json
            return ParseConfig(fileContents);
        }
    }

Я получаю доступ к значению Options.UseFeature из нескольких задач. У меня, кажется, есть некоторые части программы, где значения оказываются истинными, а некоторые - где ложными, но только в некоторых случаях. Мой мыслительный процесс заключается в том, что я знаю, что из-за нескольких потоков cachedUseFeature = ToolBox.Config.Flights.IsActive("UseFeature", overrideName); можно вызывать несколько раз. Тем не менее, я не понимаю, как это могло бы дать разные ответы в разное время, как это называется. Решит ли это ленивое значение для cachedUseFeature или что-то еще происходит? Глядя на Является ли Lazy хорошим решением для поточно-ориентированного загруженного синглтона? , я испытываю желание поставить блокировку вокруг Toolbox.Config везде, где он используется, но я не уверен, что этоправильное решение тоже.

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Вы можете сделать Options одиночным и выполнить следующую строку в приватном конструкторе одиночного

cachedUseFeature = ToolBox.Config.Flights.IsActive("UseFeature", overrideName);
0 голосов
/ 17 октября 2019

Простая мьютексная синхронизация обычно выполняется с помощью блока блокировки.

  1. добавить выделенный объект для блокировки. Нечто личное, что никто не может увидеть. Никогда не пытайтесь заблокировать что-то, что вы выдаете.
  2. Оберните весь код, который требует взаимного исключения, в блок блокировки.
  3. Это означает, что вы захотитезакодировать каждую функцию get и set. Так что больше не нужно автоматически реализовывать свойства. Я не знаю ни одного синтаксического сахара, который бы помог вам с этим справиться.

    private object mutex = new object();
    public bool UseFeatureInternal {
      get {
         lock(mutex){
           //put all get code - including return statements - into this block
         }
      }
      set {
         lock(mutex){
           //put all set code here
         }
      }
    }
    

Но, как отмечали другие, на самом деле это может быть не тот дроид, которого вы ищете.

...