C# статическая блокировка свойства

У меня была некоторая удача с Сервисная Обертка Java

7
задан Charles Bryant 27 August 2010 в 23:59
поделиться

4 ответа

10k просмотров - это одно каждые 8 ​​секунд ... не уверен, что вам нужно слишком сильно беспокоиться ... ;-p

Но вернемся к коду - это слишком усложняет ситуацию, и вы все еще может в конечном итоге инициализировать его дважды. Я бы просто использовал для этого статический конструктор; он будет более надежным. Если вы должны иметь полную изолированную ленивую загрузку (даже с другими статическими методами для этого типа), есть трюк с внутренним классом для достижения того же:

public class MyClass
{
    static class InnerCache {
        internal static readonly IList<Entry> _listCache;
        static InnerCache() {
            List<Entry> tmp  = new List<Entry>();
            //Add items to the list _listCache from XML file
            _listCache = new ReadOnlyCollection<Entry>(tmp);
        }
    }
    protected static IList<Entry> ListCache {
        get {return InnerCache._listCache;}
    }
}

Я также был бы обеспокоен вероятностью кто-то изменяет список - возможно, он захочет использовать список только для чтения!

13
ответ дан 6 December 2019 в 10:00
поделиться

На самом деле нет причин, по которым это не сработает для вас. Однако, если вы хотите сделать это так, как ваш пример кода, вам нужно заблокировать его, прежде чем проверять, имеет ли _listCache значение null. Таким образом, вам понадобится отдельный монитор для блокировки. Примерно так:

public class MyClass
{
        private static object _listCacheMonitor = new object();
        private static List<Entry> _listCache = null; 
        protected static List<Entry> ListCache
        {
            get
            {
                lock (_listCacheMonitor) {    
                    if (_listCache == null)
                    {
                        _listCache = new List<Entry>();
                        //Add items to the list _listCache from XML file
                    }
                }
                return _listCache;
            }
        }
        //....Other methods that work with the list
}
3
ответ дан 6 December 2019 в 10:00
поделиться

Статический конструктор может быть вашим лучшим выбором здесь. Статический конструктор блокирует все зависящие от него потоки во время его работы и запускается только один раз. Поскольку у вас есть код, блокировка на самом деле ничего не делает, и есть много способов, которыми могут случиться плохие вещи, включая одновременную инициализацию нескольких списков из XML. По факту,

2
ответ дан 6 December 2019 в 10:00
поделиться

Несколько потоков могут инициализировать _listCache. В зависимости от оптимизации генерации кода и оптимизации выполнения во время выполнения это может привести к блокировке нескольких потоков и обновлению различных объектов. Кроме того, вы не можете раскрыть список как свойство, позволяющее кому-либо добавлять / удалять объект без блокировки.

Лучше использовать неизменяемый список, который несколько читателей могут безопасно анализировать в режиме только для чтения. В качестве альтернативы вы можете использовать блокировку чтения-записи, но между контролем инициализации и контролем доступа rw будет довольно сложно.

1
ответ дан 6 December 2019 в 10:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: