使用时钟滴答作为随机数种子

时间:2012-06-05 19:26:15

标签: c# sql-server random

我正在使用当前时钟滴答作为随机数生成的种子。随机数用于伪GUID,我的数据库中的检查将确保它在返回之前不存在。平均而言,这个方法将在过程的生命周期中连续调用大约10k次。

我担心的是,可能会背靠背生成相同的数字,导致对我的数据库进行多次不必要的递归调用,检查是否存在相同的ID。如果可能的话,我想避免这种情况。测试这种情况的最佳方法是什么?

如果重要,应用程序是.NET 4,数据库是SQL Server 2008。

private static string GenerateUniqueDelId()
{
    // Generate a random integer using the current number of clock ticks as seed.
    // Then prefix number with "DEL" and date, finally padding random integer with leading zeros for a fixed 25-character total length.
    int seed = (int)DateTime.Now.Ticks;
    Random number = new Random(seed);
    string id = string.Format("DEL{0}{1}", DateTime.Today.ToString("yyyyMMdd"), number.Next().ToString("D14"));

    // Lookup record with generated ID in Sesame. If one exists, call method recursively.
    string query = "SELECT * FROM Lead WHERE Esm_Id = @Esm_Id";
    SqlParameter[] parameters = { new SqlParameter("@Esm_Id", id) };
    if (DataManager.GetRow(query, parameters, DelConnection.Sesame) != null) return GenerateUniqueDelId();

    // Otherwise, return ID.
    return id;
}   //// End GenerateUniqueDelId()

2 个答案:

答案 0 :(得分:11)

您的关注点是正确的:您应该将Random实例的创建移出方法体 - 否则您将使用相同的值重新播种多次,从而产生相同的数字序列。< / p>

此外,您还在重新发明轮子:Random类的默认构造函数已将当前时钟时间用作默认种子。

问题是为什么不避免所有这些,只是在数据库端使用自动生成的Guid?

答案 1 :(得分:7)

引用Jon Skeet

  

当您在Stack Overflow上的问题标题中看到“随机”一词时,几乎可以保证它与无数类似问题的基本问题相同。本文将介绍为什么随机性会导致很多问题,以及如何解决这些问题。

查看他关于随机数生成器的文章

http://csharpindepth.com/Articles/Chapter12/Random.aspx

基本上他的解决方案看起来像:

using System;
using System.Threading;

public static class RandomProvider
{    
    private static int seed = Environment.TickCount;

    private static ThreadLocal<Random> randomWrapper = new ThreadLocal<Random>(() =>
        new Random(Interlocked.Increment(ref seed))
    );

    public static Random GetThreadRandom()
    {
        return randomWrapper.Value;
    }
}