Я конвертировал некоторый код С# в vb.net, и converter.telerik.com сделал это:
i--;
в это:
System.Math.Max(System.Threading.Interlocked.Decrement(i), i + 1)
Что со всей фантазией?
Я конвертировал некоторый код С# в vb.net, и converter.telerik.com сделал это:
i--;
в это:
System.Math.Max(System.Threading.Interlocked.Decrement(i), i + 1)
Что со всей фантазией?
Комментарий Michał Piaskowski вызвал следующее объяснение:
Семантика i--
в С# должна вернуть текущее значение i
(т.е. значение до начала декремента), а затем уменьшить i
на единицу.
Итак, нам нужно преобразовать это в VB. Мы не можем использовать i -= 1
, потому что это не возвращает текущее значение i
до декремента. Итак, нам нужна операция, которая уменьшит i
, но вернет значение i
до декремента, что-то вроде:
Function DoPostDecrement(ByRef i As Integer) As Integer
i -= 1
Return i + 1
End Function
Но это предполагает использование следующего, чтобы избежать необходимости писать метод для выполнения вышеперечисленного:
System.Math.Max(
someValueThatIsEqualToiMinusOne,
someValueThatIsEqualtoiBeforeTheDecrement
)
Но VB.NET не позволит вам использовать i -= 1
или i = i - 1
вместо someValueThatIsEqualToiMinusOne
. Однако System.Threading.Interlocked.Decrement(i)
является допустимым и равным значению i - 1
. Как только вы это сделаете, поскольку параметры оцениваются слева направо, someValueThatIsEqualtoiBeforeTheDecrement
должен быть i + 1
(в этот момент декремент был выполнен до i + 1
- это значение предварительного декремента.
Обратите внимание, что приведенный выше метод DoPostDecrement
и конструктор System.Math.Max, System.Threading.Interlocked.Decrement
могут иметь разную семантику в многопоточном контексте.
Операция с блокировкой atomic; в многопоточных контекстах вы можете безопасно использовать его, не удерживая блокировку, если вы будете осторожны.
Единственная причина, по которой я вижу, - это
Уменьшает указанную переменную и сохраняет результат, как атомный операции.
Это зависит - есть ли "i" общая переменная? Это в потокобезопасной среде?
Если "i" является целым числом, то i-- делает по существу следующее (игнорируя детали):
Как вы можете видеть, есть > 1 шаг. Если "i" находится в потокобезопасном месте (статическая переменная, разделенная по потокам и т.д.), Тогда поток может потенциально остановиться в середине этих двух шагов, другой поток может выполнить оба действия, а затем вы будете иметь проблема с недопустимыми данными.
Класс Interlocked по существу объединяет два этапа выше в один шаг, обеспечивая атомную операцию. Теперь вам не нужно беспокоиться о потоках, поскольку это одна операция и не может быть прервана другим потоком.
Чтобы ответить на ваш вопрос, выглядит так: converter.telerik.com
вещь чрезмерно консервативна в отношении проблем с потоками. WAAAY слишком консервативен. Я вернул бы код в i--
, если один и тот же экземпляр i
не будет мутироваться из нескольких потоков одновременно.