Генерация уникальных числовых идентификаторов с использованием DateTime.Now.Ticks - PullRequest
14 голосов
/ 28 сентября 2011

Мне нужно создать уникальный числовой идентификатор для присоединения к входящему запросу. Этот идентификатор используется только временно для отслеживания запроса и будет удален после завершения обработки запроса. Этот идентификатор будет использоваться только в контексте данного приложения, но его необходимо будет назначать высокопроизводительным многопоточным способом.

Я думал об использовании DateTime.Now.Ticks для этого идентификатора, но хотел бы знать, может ли DateTime.Now.Ticks все еще генерировать конфликтующий идентификатор, если одновременные запросы обрабатываются одновременно?

Если кто-нибудь может предложить лучший способ для генерации этих идентификаторов (желательно не Int64, как у Тика) в многопоточной среде, пожалуйста, дайте мне знать. Чего-то простого, например, возрастающего числа, будет достаточно даже для того, чтобы мне не пришлось блокировать число перед увеличением.

Большое спасибо за любую помощь.

Ответы [ 5 ]

8 голосов
/ 28 сентября 2011

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

// Declaration
private static int safeInstanceCount = 0;

// Usage
{
      ...
      Interlocked.Increment(ref safeInstanceCount);
      ...
}
6 голосов
/ 28 сентября 2011

DateTime.Now абсолютно ужасен для этой цели.В лучшем случае у вас будет разрешение 1 миллисекунда;в худшем случае - 17 мс для NT и 1 секунда (!) для CE / Compact Framework.

Рассмотрите возможность использования метода Interlocked.Increment для быстрого, поточно-ориентированного счетчика.

4 голосов
/ 28 сентября 2011

Начните с идентификатора для каждого потока (если запросы генерируются несколькими потоками), объединенного со счетчиком для каждого потока (если ожидается, что каждый поток инициирует более одного запроса).

2 голосов
/ 28 сентября 2011

Просто получите сильное случайное число или используйте GUID

Если ДОЛЖНА быть обеспечена высокая производительность, выделяйте последовательные числа в монотонной последовательности. Предотвратите конфликт блокировки, «зарезервировав» диапазон (скажем, 20-100) идентификаторов для каждого потока, который обрабатывает сообщения. Таким образом, вам нужно будет заблокировать генератор последовательности только один раз в 20-100 итераций.

0 голосов
/ 29 сентября 2011

Если вы знаете, сколько потоков у вас будет (или хотя бы верхнюю границу), вы можете поделить пространство идентификаторов между своими потоками, вычислив идентификатор как значение (локального) потока иID потока - например, counter_value++ << 8 | thread_id.Таким образом, не требуется никакой координации или блокировки между потоками, а для генерации идентификатора требуется только инкремент, битовое смещение и или.

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

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