2010-07-20 3 views
3

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

+0

Каковы типы объектов и как они используются в других местах? – ULysses

+0

Интересно, как долго оригинальный разработчик продолжал использовать Interlocked.Equals, считая, что он должен быть действительной «безопасной» функцией сравнения, поскольку он был блокирован и скомпилирован. –

+0

@ Dan: По-видимому, надолго; Я нашел Interlocked.Equals повсюду в разных потоках. :(Я не эксперт по потокам, но, по крайней мере, я знаю, что я не эксперт. –

ответ

5

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

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

Update:

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

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

+9

Atomic! = Volatile. Вы можете в итоге прочитать устаревшие данные. –

+0

Да, некоторые из значений являются общими. Я добавлю эту деталь к своим вопросам. –

+0

@Jon: Вы правы. Мой ответ обновлен. –

6

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

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

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

+0

Это должен был быть «массив структур». Извините, плохое редактирование с моей стороны Я исправил это в своем вопросе. –

+0

@Bill W: Хорошо, удалено. –

Смежные вопросы