SyncLock на нулевом объекте - PullRequest
2 голосов
/ 25 марта 2011

Существует ли простой способ SyncLock для объекта, который может быть нулевым?

И прежде чем вы попросите об этом, да, я знаю, что не логично выполнять SyncLock для пустой переменной.Однако это упростило бы мой код, потому что сейчас у меня нет выбора, кроме как выполнить нулевую проверку повсюду перед вызовом SyncLock.

If myObjectA Is Nothing Then
  myObjectA = myObjectB
Else
  SyncLock myObjectA
    myObjectA = myObjectB
  End SyncLock
End If

Ответы [ 3 ]

4 голосов
/ 25 марта 2011

Да, используйте вспомогательный объект.

Вы не должны назначаться myObjectA, если он используется в качестве блокировки.

С MSDN :

Блокировка значения объекта. Значение Локобъект не может быть ничем. Вы должны создать объект блокировки перед использованием это в операторе SyncLock.

Вы не можете изменить значение объект блокировки во время выполнения SyncLock блок. Механизм требует, чтобы объект блокировки остается без изменений.

3 голосов
/ 25 марта 2011

Нет, вы не можете использовать нулевую ссылку в качестве идентификатора для блокировки.

Вы даже не можете использовать ссылку в качестве идентификатора, если она может быть нулевой, поэтому ваш текущий код не является потокобезопасным.Вы должны использовать другой способ идентифицировать замок.Два разных потока могут заменить нулевую ссылку без возможности исключить друг друга, что приведет к перезаписи одной ссылки другой:

If myObjectA Is Nothing Then
  ' Here another thread can change the reference, believing that it's safe
  myObjectA = myObjectB
Else
  SyncLock myObjectA
    myObjectA = myObjectB
  End SyncLock
End If
3 голосов
/ 25 марта 2011

Вероятно, существует некоторый рефакторинг, который поможет избежать таких ситуаций. Этот код кажется странным. присваивание переменной блокировки объекта, если он равен нулю, и блокировка, если не кажется, что-то неправильно Кроме того, вы блокируете, а затем меняете переменную блокировки!

Помните, что блокировка относится к ссылке, а не к значению! По сути, он блокирует доступ к указанной ссылке из всех блоков кода, не входящих в блокировку.

...