2012-06-05 15 views
5

Estoy usando las marcas de reloj actuales como una semilla para la generación de números aleatorios. El número aleatorio se usa en un pseudo GUID y una comprobación en mi base de datos se asegurará de que no exista antes de volver. En promedio, este método se llamará alrededor de 10 veces por semana durante la vida del proceso.Uso de marcas de reloj como número aleatorio semilla

Mi preocupación es que un número idéntico podría generarse de forma consecutiva, lo que da como resultado múltiples llamadas repetitivas innecesarias a mi base de datos que buscan el mismo ID. Me gustaría evitar esto si es posible. ¿Cuál es la mejor manera de probar este escenario?

si importa, es la aplicación .NET 4 y la base de datos es 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() 
+3

Si vas a SQL Server para comprobar su exitancia -por qué no puede usted los genera allí en el primer lugar? – YavgenyP

+0

Como alternativa al uso de un número aleatorio, ¿puede usar una columna 'Identity' en su lugar? – Matthew

+2

¿Por qué no utilizar un GUID? No soy un gran fan de volver a crear una rueda. –

Respuesta

10

Tiene usted razón en su preocupación: Debe moverse la creación de su Random ejemplo de su cuerpo método - de lo contrario volverá a sembrar con el mismo valor muchas veces, lo que dará como resultado la misma secuencia numérica.

También está volviendo a inventar la rueda: el constructor predeterminado de la clase Random ya usa la hora actual del reloj como valor predeterminado.

La pregunta es ¿por qué no evita todo esto y simplemente utiliza un Guid autogenerado en el lado de la base de datos?

+0

La ID se está utilizando en un sistema de proveedor externo y tiene criterios de formato específicos: 25 caracteres de longitud, con el prefijo 3 caracteres alfabéticos y la fecha en formato ayyyMMdd. Solo puedo jugar realmente con los 14 caracteres restantes. – Brian

+1

Ah, y con respecto al constructor aleatorio predeterminado, gracias por la información. No sabía que utiliza marcas de reloj por defecto. ¡Me aseguraré de actualizar esto en mi código! – Brian

+1

Terminé moviendo 'Random' fuera de mi loop para poder pasarlo a' GenerateUniqueDelId (generador aleatorio) '. – Brian

6

Citando Jon Skeet

Cuando vea la palabra "aleatorio" en un título de la pregunta sobre el desbordamiento de pila casi se puede garantizar que será el mismo problema fundamental como un sinnúmero de preguntas similares. Este artículo analiza por qué la aleatoriedad causa tantos problemas y cómo abordarlos.

revisar su artículo sobre generadores de números aleatorios

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

básicamente su solución se parece a:

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; 
    } 
} 
+0

Gracias, definitivamente leeré este artículo. – Brian

+0

Aún recibí duplicados usando Environment.TickCount como semilla. Terminé usando (int) DateTime.UtcNow.Ticks y aún no he recibido ningún resultado duplicado. –

+0

@JoshDeLong - Eso es lo divertido de la aleatoriedad; No promete nunca entregar duplicados :) –

Cuestiones relacionadas