Нет смысла создавать поточный синглтон, если ваши свойства не будут поточно-ориентированными.
Вы должны либо заблокировать присваивание поля _localization
, либо создать экземпляр в конструкторе вашего синглтона ( предпочтительно ). Любое предложение, которое относится к экземпляру синглтона, относится к этому ленивому экземпляру свойства.
То же самое относится и ко всем свойствам (и их свойствам) Localization
. Если это Singleton, это означает, что любой поток может получить к нему доступ в любое время, и простая блокировка геттера снова ничего не сделает.
Например, рассмотрим этот случай:
Thread 1 Thread 2
// both threads access the singleton, but you are "safe" because you locked
1. var loc1 = Params.Localizations; var loc2 = Params.Localizations;
// do stuff // thread 2 calls the same property...
2. var value = loc1.ChunkSize; var chunk = LC.Loc("params.chunksize");
// invalidate // ...there is a slight pause here...
3. loc1.RebuildLocalizations();
// ...and gets the wrong value
4. var value = chunk.To();
Если вы только читаете эти значения, то это может не иметь значения, но вы можете видеть, как вы легко можете столкнуться с этим подходом.
Помните, что при работе с потоками вы никогда не знаете, будет ли другой поток выполнять что-то между двумя инструкциями. Только простые 32-битные назначения являются атомарными , ничего больше.
Это означает, что в этой строке здесь:
return LC.Loc("params.chunksize").To<int>();
, что касается потоков, эквивалентно:
var loc = LC.Loc("params.chunksize");
Thread.Sleep(1); // anything can happen here :-(
return loc.To<int>();
Любая нить может перейти между Loc
и To
.