2012-06-28 1 views
9

Недавно у меня возникли проблемы с классом singelton, который был ленивым, инициализируя словарь, где второй поток попытается использовать его до того, как он был заполнен. Поэтому я реализовал инициализацию переменных с помощью класса Lazy<T>.Используется Lazy <T> Плохо для исполнения?

Вот мой код:

private static Dictionary<string, string> GroupDefaults 
{ 
    get { return mGroupDefaults.Value; } 
} 
private static Lazy<Dictionary<string, string>> mGroupDefaults = 
    new Lazy<Dictionary<string,string>>(delegate 
    { 
     Dictionary<string, string> defaults = new Dictionary<string, string>(); 
     foreach (KeyValuePair<string, UnitGroup> groupDef in Groups) 
      defaults.Add(groupDef.Key, groupDef.Value.First().Key); 
     return defaults; 
    }); 

Эта проблема решена, и теперь я рассматриваю это делаю регулярную практику шахты использовать Lazy<T> класс в любом месте я ленивые инициализации, чтобы избежать возможных проблем многопоточности. Так что в основном я хотел бы знать, хорошая ли это практика? Или это будет слишком сложно для исполнения или чего-то еще?

ответ

10

Сложно сказать, не зная, какие ограничения производительности у вас есть, но по моему опыту одноразовая инициализация редко является узким местом (поскольку по определению это происходит только один раз.) Lazy<T> было написано, чтобы предоставить вам это точное обслуживание, поэтому я бы рекомендовал его использовать.

+0

Значит, это хорошая практика использования класса Lazy ? –

+2

@ AlexHopeO'Connor Вот почему он был добавлен! Недостатком использования класса является то, что объявление поля/свойства становится немного грязнее (как вы можете видеть), но с точки зрения производительности, оно твердое. – dlev

+2

Это все, что мне нужно было услышать, просто я не видел много примеров этого в коде других народов. –

1

Я думаю, вы можете использовать Lazy для не предназначенного для использования. Lazy должен использоваться для ситуаций, когда что-то имеет большую стоимость инициализации, но существует вероятность того, что он не может использоваться в течение всего срока службы объекта.

Если вы всегда вызывать GroupDefaults по крайней мере один раз за это время жизни лучшего методом был бы инициализировать GroupDefaults в фоновом потоке в начале срока службы контейнера и надеется, что это будет сделано до того, как это делается инициализация (я знаю, что есть класс для этого, но мне нужно копать в MSDN, чтобы найти его)

+1

Хотя я согласен с тем, что это предполагаемый прецедент, он * также * правильно выполняет инициализацию потокобезопасности, поэтому вам не нужно беспокоиться об этом сами. – dlev

+0

Я инициализировал его из другого потока, однако инициализация не завершилась до того, как другие вещи, загруженные бок о бок, попытались получить к нему доступ. Это очень странная ситуация, когда я не могу позволить себе загружать последовательно, поскольку это добавило бы достаточное количество времени для загрузки. Поэтому я создаю ряд потоков, которые выполняют достаточную работу, прежде чем они будут подняты из-за того, что GroupDefaults не инициализируется, что приводит к общему увеличению времени загрузки. Однако я в основном спрашиваю, что будет отрицательным эффектом использования этого класса? Каковы его стороны? –

2

Если это для одноэлементного, то static constructor может быть тем, что вы хотите. Что-то вроде:

class MySingleton 
{ 
    static MySingleton() 
    { 
     Instance().InitDict(); 
    } 
} 
3

Из документации, я нахожу следующее:

Если ни один делегат не передается в конструктор Ленивый, обернутый типа создается с помощью Activator.CreateInstance, когда значение свойства сначала открывается. Если тип не имеет конструктора по умолчанию, генерируется исключение во время выполнения.

Activator.CreateInstance - это метод, который, как известно, плохо подходит для работы. Однако это не кажется проблемой в вашем случае, и, во всяком случае, как сказал длев, вызов метода однажды не будет проблемой. Я не видел Lazy<T> очень часто, но я не вижу причин не использовать его в вашем случае.

 Смежные вопросы

  • Нет связанных вопросов^_^