使用DateTime.Now.Ticks生成唯一数字ID

时间:2011-09-28 00:08:46

标签: c# .net multithreading algorithm concurrency

我需要生成一个唯一的数字ID来附加到传入的请求。此ID仅用于临时跟踪请求,并在请求完成处理后将被丢弃。此ID仅在此应用程序的上下文中使用,但需要以高性能多线程方式分配。

我在考虑使用DateTime.Now.Ticks获取此ID,但是想知道如果同时处理同时请求,DateTime.Now.Ticks是否仍会生成冲突ID?

如果有人可以在多线程环境中建议更好的方法来生成这些ID(最好不是像Int这样的Int64),请告诉我。如果只是在递增之前我不必锁定数字,那么像递增数字一样简单就足够了。

非常感谢您的帮助。

6 个答案:

答案 0 :(得分:8)

您只需要使用一个静态变量,每当您想要另一个唯一值时,该变量就会递增。您可以使用Interlocked.Increment方法...

使此线程安全且速度非常快
// Declaration
private static int safeInstanceCount = 0;

// Usage
{
      ...
      Interlocked.Increment(ref safeInstanceCount);
      ...
}

答案 1 :(得分:6)

为此目的,{p> DateTime.Now绝对可怕。充其量,你的分辨率为1毫秒;在最坏的情况下,NT上为17 ms,CE / Compact Framework上为1秒(!)。

考虑将Interlocked.Increment方法用于快速,线程安全的计数器。

答案 2 :(得分:4)

从每个线程ID开始(如果多个线程发起请求),与每个线程计数器连接(如果每个线程预计会发起多个请求)。

答案 3 :(得分:2)

只需获得一个强大的随机数或使用GUID

如果高性能是必须具有的功能,请以单调的顺序分配序列号。通过“保留”处理消息的每个线程的一系列(例如,20-100)ID来防止锁争用。这样,您需要在20-100次迭代中仅锁定序列生成器一次。

答案 4 :(得分:0)

如果你知道你将拥有多少个线程(或者至少是一个上限),你可以在你的线程之间划分你的ID空间,计算ID作为(线程本地)计数器的值和线程的ID - 例如counter_value++ << 8 | thread_id。因此,不需要线程之间的协调或锁定,并且生成ID只需要增量,位移和或。

如果您使用系统线程ID,您的ID会稍长,但您无需手动为线程分配ID。

答案 5 :(得分:-1)

可以使用这个属性但是支付 1ms 这并不重要!

public static long UniqId { 
    get { 
        Thread.Sleep(1); 
        return long.Parse(DateTime.Now.ToString("yyMMddHHmmssffff")); 
    } 
}