Присвоение значения функции вместо использования ключевого слова Return и его влияние на синхронизированное выполнение кода

#vb.net #synchronization #return

#vb.net #синхронизация #Возврат

Вопрос:

Мне интересно, есть ли разница между использованием

 Public Function Foo() As Double
  Return 3.0
End Function
  

и

 Public Function Foo() As Double
  Foo = 3.0
End Function
  

но конкретно в отношении выполнения кода.

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

Я понимаю, что строки кода после ‘Return’ не выполняются, потому что функция теряет фокус, но что, если ‘Return’ заключен в блок SyncLock?

 Public Function Foo() As Double
  SyncLock fooLock 
    Return 3.0
  End SyncLock
End Function
  

Вызывается ли End SyncLock? Является ли блок SyncLock сокращением для:

 Public Function Foo() As Double
  Dim result as Double
  Try
    Threading.Monitor.Enter(fooLock)
    result = 3.0
  Finally
    Threading.Monitor.Exit(fooLock)
  End Try
  Return result
End Function
  

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

 Public Sub DoSomething()
  Dim a As Double = Foo
  ...Do other things
End Sub


Public Function Foo() As Double
  Try
    Threading.Monitor.Enter(fooLock)
    Return 3.0
  

…код, возвращаемый в executes, ‘a’ присваивается возвращаемому значению Foo, тогда, возможно, все другие задачи в потоке выполнены, тогда

   Finally
    Threading.Monitor.Exit(fooLock)
  End Try
End Function
  

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

Кто-нибудь может помочь мне прояснить эти концепции?

Ответ №1:

Определенно есть разница между RETURN 3 и v = 3

Return X завершает вызов прямо на этом месте, но он определенно выполняется через все открытые вами try catch finally.

v = 3 просто устанавливает возвращаемое значение как 3, но не возвращает. Выполнение продолжается в функции до завершения функции или завершения функции.

Я не уверен на 100% в вопросе synclock, но я бы поспорил, что возврат из него завершит его должным образом.

Комментарии:

1. Я вполне уверен, что блок SyncLock вернется правильно и также выйдет из блокировки, но если рассматривать SyncLock как эквивалентный ему явный код, вопрос все равно будет заключаться в том, когда именно будет вызван блок effectife ‘Finally’. В случае моего реального кода я использую ReaderWriterLock, поэтому необходимо учитывать особенности структурирования кода, SyncLock — это скорее академическая дискуссия о том, что он на самом деле делает.

Ответ №2:

Пожалуйста, больше не используйте шаблон «присвоить функции имя значения и вернуть». Для REM некоторых из нас это актуально.

Тем не менее, если вы посмотрите на IL, сгенерированный из кода, который использует return vs. присвоить имя функции, вы увидите, что оно на 100% совпадает.

Что касается вашего другого вопроса, согласно MSDN:

Блок SyncLock гарантирует снятие блокировки, независимо от того, как вы выходите из блока

Комментарии:

1. Первоначальное намерение использовать этот шаблон было связано с конкурирующим фактом, что ничего, включая потоковую обработку. Monitor.Exit() будет выполнен после инструкции Return, когда мне нужно свойство, возвращаемое значение которого соответствующим образом заблокировано для чтения во время использования.