Что использовать вместо Interlocked.Equals - PullRequest
3 голосов
/ 20 июля 2010

У меня есть устаревший код, который использует Interlocked.Equals для сравнения значений.Значения могут быть двумя значениями типа bools или могут сравнивать массив структур с нулем.Resharper жалуется на Interlocked.Equals, говоря «доступ к статическому члену типа через производный тип».Я знаю, что Equals не является членом класса Interlocked, а скорее является членом класса объекта.Сравнение происходит в потоке, поэтому я предполагаю, что исходный кодер хотел сделать сравнение как элементарную операцию, отсюда и использование Interlocked.Так как object.Equals не является атомарным, каков правильный, потокобезопасный способ проведения подобных сравнений?Обратите внимание, что большая часть данных является статической, а часть статической изменчивой.

Ответы [ 2 ]

6 голосов
/ 20 июля 2010

Вы не можете сделать все сравнение атомарным, но вас интересует не атомарность. Я подозреваю, что это изменчивость.Это то, что гарантирует, что когда вы читаете значение, вы определенно получаете самую последнюю версию, а не видите значение, которое было допустимым в какой-то момент в прошлом, но может и не быть.Если вам действительно нужна атомарность в части чтения / чтения / сравнения, я подозреваю, что вам понадобится блокировка.

Вы можете использовать Interlocked.CompareExchange дляуверен, что вы читаете самое последнее значение.

Вам обязательно нужно использовать поточность без блокировки?Я настоятельно рекомендую либо строить поверх более крупных структур (например, Parallel Extensions), либо просто использовать блокировки для общих данных (которых следует избегать, где это возможно, в любом случае).

5 голосов
/ 20 июля 2010

Одиночные чтения логических значений или ссылок на объекты являются атомарными. Таким образом, если вы сравниваете одно общее значение с константой или локальной переменной, «блокировка» не требуется. Как сказал Джон, вам нужно будет использовать Interlocked.CompareExchange, чтобы убедиться, что вы читаете последнее записанное значение, если общие переменные не равны volatile.

Если оба сравнения используются совместно, вам понадобится реальная блокировка. Не существует способа атомарного сравнения двух общих значений AFAIK.

Обновление:

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

Если вы подумаете об этом, что бы вы сделали с результатом сравнения? Это на самом деле не имеет смысла; как только у вас будет результат, это может быть неправильно. Блокировка должна храниться дольше, чем просто для того, чтобы сравнение было полезным для чего-либо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...