С# версия синхронизированного ключевого слова java?

Есть ли у С# своя версия Java-синхронизированного ключевого слова?

т.е. в java он может быть указан либо для функции, объекта или блока кода, например:

public synchronized void doImportantStuff() {
   // dangerous code goes here.
}

или

public void doImportantStuff() {
   // trivial stuff

   synchronized(someLock) {
      // dangerous code goes here.
   }
}

Ответ 1

Сначала - большинство классов никогда не должны быть потокобезопасными. Используйте YAGNI: используйте только безопасность потоков, когда вы знаете, что собираетесь использовать ее (и протестируйте ее).

Для материала уровня метода существует [MethodImpl]:

[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}

Это также можно использовать для аксессуаров (свойств и событий):

private int i;
public int SomeProperty
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    get { return i; }
    [MethodImpl(MethodImplOptions.Synchronized)]
    set { i = value; }
}

Обратите внимание, что по-умолчанию синхронизированные по-разному события синхронизируются, тогда как автоматически реализуемые свойства не являются:

public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized

Лично мне не нравится реализация MethodImpl, поскольку он блокирует this или typeof(Foo) - что противоречит лучшей практике. Предпочтительным вариантом является использование ваших собственных блокировок:

private readonly object syncLock = new object();
public void SomeMethod() {
    lock(syncLock) { /* code */ }
}

Обратите внимание, что для полевых событий реализация блокировки зависит от компилятора; в старых компиляторах Microsoft это lock(this)/lock(Type) - однако запись в блоге (позже revisited).

Ответ 2

static object Lock = new object();

lock (Lock) 
{
// do stuff
}

Ответ 3

Есть ли у С# своя версия Java-синхронизированного ключевого слова?

Нет. В С# вы явно используете lock ресурсы, которые вы хотите работать синхронно через асинхронные потоки. lock открывает блок; он не работает на уровне метода.

Однако основной механизм похож, поскольку lock работает, вызывая Monitor.Enter (и впоследствии Monitor.Exit) во время выполнения. Java работает так же, в соответствии с Sun documentation.

Ответ 4

Вместо этого вы можете использовать инструкцию lock. Я думаю, что это может заменить только вторую версию. Кроме того, помните, что для необходимо использовать synchronized и lock.

Ответ 5

Обратите внимание, что с полными путями строка: [MethodImpl(MethodImplOptions.Synchronized)] должна выглядеть как

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]