2009-02-24 140 views
2

在应用程序,创建特殊类型的对象的时候,我需要生成一个唯一ID为他们每个人。这些对象是在工厂创建的,并且很有可能在“批量”操作中创建。我认识到“随机”从框架毕竟不是那么“随机”,所以我试图追加时间戳如下:备用唯一ID生成技术

private string GenerateUniqueId() 
{ 
    Random randomValue = new Random(); 
    return DateTime.Now.Ticks.ToString() + randomValue.Next().ToString(); 
} 

不幸的是,即使这是行不通的。

private string GenerateUniqueId() 
{ 
    Random randomValue = new Random(); 
    int value = randomValue.Next(); 
    Debug.WriteLine(value.ToString()); 
    Thread.Sleep(100); 
    return DateTime.Now.Ticks.ToString() + value.ToString(); 
} 

因为这不是一个非常大的应用程序:对于在连续快速创建的对象,我产生相同的唯一标识:-(

目前,我在一个粗暴的方式如下实现它我想简单快捷的技术就足够了,而不是实现一个复杂的算法

请建议

+0

你不应该创建方法里面的`Random`对象。有一个静态对象(或者``ThreadStatic``),这样你就可以保证一串伪随机数。你可能不需要`DateTime.Now。蜱“然后。但使用GUID是一个更好的主意。 – 2009-02-24 18:34:32

回答

11

一个GUID可能是你在找什么:。

private string GenerateUniqueId() 
{ 
    return Guid.NewGuid().ToString("N"); 
} 

如果你想要一个更小,更易于管理的ID,那么你可以使用这样的事情:

private string GenerateUniqueId() 
{ 
    using (var rng = new RNGCryptoServiceProvider()) 
    { 
     // change the size of the array depending on your requirements 
     var rndBytes = new byte[8]; 
     rng.GetBytes(rndBytes); 
     return BitConverter.ToString(rndBytes).Replace("-", ""); 
    } 
} 

注意:这只会给你相比,GUID的128位的64位数字,所以会有更多的碰撞机会。虽然在现实世界中可能不是问题。如果这是一个问题,那么你可以增加byte数组的大小来生成一个更大的ID。

+0

@Codex:Thread.Sleep是一个可怕的想法。你会像这样杀死你的应用程序性能。 – casperOne 2009-02-24 16:38:59

+0

@Luke:谢谢。但是,我进一步使用UniqueId作为文件名来将对象序列化到磁盘。它有点麻烦,以处理 @casperOne:点指出!将尽快摆脱它... – Codex 2009-02-24 17:07:31

1

假设你不想要一个GUID,第一种选择将是一个静态字段,并互锁:

private static long lastId = 0 
private static long GetNextId() { 
    return Interlocked.Increment(ref lastId); 
} 

如果你想要的东西,基于时间蜱,记得上次值,如果相同的手动递增,保存;否则只保存:

private static long lastTick = 0; 
private static object idGenLock = new Object(); 
private static long GetNextId() { 
    lock (idGenLock) { 
    long tick = DateTime.UtcNow.Ticks; 
    if (lastTick == tick) { 
     tick = lastTick+1; 
    } 
    lastTick = tick; 
    return tick; 
    } 
} 

(这两种方法都不就会好多个进程。)

1

在您的意见法典你说使用的唯一ID作为文件名。有用于生成加密安全文件名,Path.GetRandomFileName()

,因为它是加密的安全,这些都是唯一的,即使在批处理操作特定的功能。该格式有点可怕,虽然它们针对文件名进行了优化,但它也可能适用于其他参考。

0

为什么不能贵厂(这大概是单线程)产生连续的唯一整数?如果你期望Random()能够工作,为什么不使用Guid()(或者其他什么是等价的)?

0

如果你打算诉诸编码自己的UUID发电机,确保盐生成。

我建议你查看open source package ossp-uuid,这是一个用于生成通用唯一标识符的ISO-C API和CLI。