Если у вас есть один общий экземпляр Config
, и все используют этот экземпляр, то есть риск, что другие потоки могут изменить свойства, пока вы их читаете.Чтобы предотвратить это, вы можете lock
получить доступ к отдельным свойствам.Но это не приятная мысль.Вместо этого лучше свести к минимуму случаи, когда вам нужно беспокоиться об этом.
Один из шагов - заставить другие ваши потоки создавать новые экземпляры Config
вместо того, чтобы все они делились.Что ваш GUI (форма?) Может получить совершенно новый экземпляр Config
.
Если у вас есть что-то подобное (например, - должно ли свойство быть публичным или как ваш класс получает , экземпляр Config
- это совсем другой вопрос.)
public Config MyConfigInstance { get; set; }
Если вы задаете это свойство, предоставляя другой экземпляр Config
с другими значениями, это атомарная операция.Вам не нужно беспокоиться, что ваш класс получит доступ к MyConfigInstance
на полпути через обновляемую ссылку.
Это может быть все, что вам нужно.Но все еще есть место для ошибки.Теперь у вашего класса есть ссылка на новый экземпляр Config
.Но какие другие потоки имеют доступ к той же ссылке и могут ли ее изменить?По крайней мере, поток, который передал его этому классу, все еще имеет доступ.Что если этот поток передает этот экземпляр, и теперь другие классы имеют ссылки на него?
Это может не быть проблемой в вашем приложении.Может быть, вы точно знаете, какие потоки имеют доступ к экземплярам каких классов.Но если что-то становится более сложным, опять же, мы бы предпочли избежать проблемы, чем пытаться отслеживать ее.
С этой целью, если несколько потоков будут совместно использовать экземпляры класса, часто предпочтительнее сделатькласс неизменный.Это примерно так:
public class MyImmutableClass
{
public MyImmutableClass(string stringValue, int intValue)
{
StringValue = stringValue;
IntValue = intValue;
}
public string StringValue { get; }
public int IntValue { get; }
}
Его свойства устанавливаются при его создании и не могут быть изменены.На данный момент вам все равно, сколько потоков имеют ссылки на экземпляр класса, потому что ни один из них не может его изменить.Вы можете заменить ссылку на один экземпляр ссылкой на новый экземпляр, но это не повлияет на другие ссылки.
Еще одно преимущество неизменного класса заключается в том, что если значения задаются только в конструкторе, вы можете проверить их.Как и в приведенном выше примере, вы можете выдать исключение, если stringValue
равно нулю.Таким образом, вы всегда знаете, что класс находится в допустимом состоянии.Невозможно создать экземпляр, который находится в недопустимом состоянии.
Мы склонны создавать изменяемые классы, потому что создавать свойства для чтения / записи быстрее, чем для конструктора.Но если мы собираемся передавать экземпляры в разные потоки, то иногда предпочтительнее начинать с неизменяемости, что заставляет нас думать и контролировать то, что может или не может быть сделано несколькими потоками.