我需要生成一个唯一的数字ID来附加到传入的请求。此ID仅用于临时跟踪请求,并在请求完成处理后将被丢弃。此ID仅在此应用程序的上下文中使用,但需要以高性能多线程方式分配。
我在考虑使用DateTime.Now.Ticks获取此ID,但是想知道如果同时处理同时请求,DateTime.Now.Ticks是否仍会生成冲突ID?
如果有人可以在多线程环境中建议更好的方法来生成这些ID(最好不是像Int这样的Int64),请告诉我。如果只是在递增之前我不必锁定数字,那么像递增数字一样简单就足够了。
非常感谢您的帮助。
答案 0 :(得分:8)
您只需要使用一个静态变量,每当您想要另一个唯一值时,该变量就会递增。您可以使用Interlocked.Increment方法...
使此线程安全且速度非常快// Declaration
private static int safeInstanceCount = 0;
// Usage
{
...
Interlocked.Increment(ref safeInstanceCount);
...
}
答案 1 :(得分:6)
DateTime.Now
绝对可怕。充其量,你的分辨率为1毫秒;在最坏的情况下,NT上为17 ms,CE / Compact Framework上为1秒(!)。
考虑将Interlocked.Increment
方法用于快速,线程安全的计数器。
答案 2 :(得分:4)
从每个线程ID开始(如果多个线程发起请求),与每个线程计数器连接(如果每个线程预计会发起多个请求)。
答案 3 :(得分:2)
只需获得一个强大的随机数或使用GUID
http://msdn.microsoft.com/en-us/library/system.guid.newguid.aspx
如果高性能是必须具有的功能,请以单调的顺序分配序列号。通过“保留”处理消息的每个线程的一系列(例如,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"));
}
}