Что такое потокобезопасный способ чтения/записи свойства С# в классе?
Я новичок в С#. В Java я могу сделать чтение/запись члена класса Java, используя "синхронизированное" ключевое слово в методе setter/getter.
Не могли бы вы рассказать мне, как правильно сделать то же самое в С#? В С# нет синхронизированного ключевого слова. Должен ли я использовать аннотацию [MethodImpl (MethodImplOptions.Synchronized)], упомянутую в С# версии синхронизированного ключевого слова java??
Или использовать Monitor.Enter(и впоследствии Monitor.Exit)?
Ответы
Ответ 1
Используйте Monitor.Enter
/Exit
(или lock
- синтаксический сахар для Monitor
) с полем private object _lock = new object()
.
Не используйте MethodImplOptions.Synchronized
. Он блокируется на this
, поэтому возможно, что какой-либо другой код будет заблокирован на том же экземпляре, который вызывает взаимоблокировки.
Блокировка экземпляра или типа, как и в случае с синхронизированным флагом, не рекомендуется для общедоступных типов, поскольку код, отличный от вашего собственного, может принимать блокировки для общедоступных типов и экземпляров. Это может вызвать взаимоблокировки или другие проблемы синхронизации.
Ответ 2
В некоторых сценариях volatile
может быть достаточно (хотя это зависит от того, что вы защищаете и что такое тип данных):
private volatile int _counter;
public int Counter
{
get { return _counter; }
set { _counter = value; }
}
ИЛИ lock
it
#region public int Counter { set; get; }
private int _counter;
private object sync_counter = new object();
public int Counter
{
set
{
lock(sync_counter)
{
_counter = value;
}
}
get
{
lock(sync_counter)
{
return _counter;
}
}
}
#endregion
Ответ 3
Как сказал Лорц, лучший способ - использовать блокировку
public class ThreadSafeSetters
{
private bool _foo;
private object _locker = new object();
public bool Foo
{
get
{
lock (_locker)
{
return _foo;
}
}
set
{
lock (_locker)
{
_foo = value;
}
}
}
}