Я не вижу убедительной причины, по которой вам нужно сделать GetHashCode
поточно-ориентированной, и я могу видеть, что это приводит к тупикам или, по крайней мере, к блокировке конвоев, если вы не будете осторожны; GetHashCode
вызывается из многих мест, которые вы можете не ожидать.
Что более логично, так это то, что если у вас несколько потоков, совместно использующих один Foo
, эти потоки должны будут синхронизировать их доступ к Foo
, поэтому у вас просто не будет вызова нескольких потоков GetHashCode
сразу (или любой другой метод Foo
).
Правильное проектирование многопоточных классов может быть трудным делом; если у вас нет очень веских причин требовать потоковые члены экземпляра, я бы предпочел не делать этого. Подавляющее большинство .NET Framework само по себе не имеет поточно-ориентированных элементов экземпляров.
Наконец, на самом деле не существует такой вещи, чтобы класс был универсально поточно-ориентированным. Вы можете синхронизировать каждый элемент экземпляра, но потребитель вашего класса может все еще испортить, если он не понимает семантику . Создание GetHashCode
поточно-ориентированного подразумевает, что вы пытаетесь учесть каждый возможный сценарий многопоточности, но даже большинство поточно-безопасных классов являются поточно-ориентированными только для определенных операций , и GetHashCode
обычно не один из них.
Я отсылаю вас к недавнему посту Эрика Липперта о безопасности потоков ; Подумайте о содержании этого при использовании фразы, такой как «Make Foo
thread-safe.»