Нет способа получить один последовательный ряд без блокировки. Неважно, какой механизм вы используете для назначения следующего значения - счетчик производительности, статическая переменная и т. Д. - когда двум потокам нужно одновременно следующее значение, один должен ждать другого.
Первое, что я сделаю, это напишу тестовую программу, которая породила большое количество потоков, каждый из которых неоднократно вызывал функцию приращения блокировки, такую как опубликованная Дэниелом Шаффером. Это позволит вам найти порог, когда ваше приложение начинает работать, где оно тратит больше времени на ожидание Monitor.Enter
, чем на что-либо еще.
Если это окажется проблемой - и я бы поспорил, что если объемы, о которых вы говорите, реальны, то это произойдет, - тогда вы должны заставить каждый поток поддерживать свой собственный последовательный счетчик, что можно сделать, пометив поле счетчика с ThreadStaticAttribute
. Затем вы можете генерировать уникальные идентификаторы из комбинации идентификатора потока и счетчика.
Этот подход не будет работать, если вы не используете пул потоков (поскольку счетчик умирает, когда поток, к которому он принадлежит). И вы, вероятно, также хотите, чтобы счетчик запуска приложения был частью составного идентификатора, чтобы вам не приходилось записывать счетчики потоков в долговременное хранилище. (Если вы этого не сделаете, при перезапуске сервера потоки начнут генерировать счетчики снова с нуля, и если ваше приложение создаст поток с тем же идентификатором, что и в предыдущем экземпляре, вы получите дубликаты идентификаторов.)
Это явно не тривиально для записи (или, что более важно, для тестирования), поэтому я определенно рекомендую доказать, что это необходимо в первую очередь.