2012-06-05 11 views
5

Ich verwende die aktuellen Clock-Ticks als Startwert für die Zufallsgenerierung. Die Zufallszahl wird in einer Pseudo-GUID verwendet und eine Überprüfung in meiner Datenbank stellt sicher, dass sie nicht existiert, bevor sie zurückgegeben wird. Im Durchschnitt wird diese Methode während der gesamten Prozessdauer etwa 10k Mal hintereinander aufgerufen.Verwenden von Clock-Ticks als Zufallszahl Seed

Meine Sorge ist, dass eine identische Nummer hintereinander erzeugt werden kann, was zu mehreren unnötigen rekursiven Aufrufen meiner Datenbank führt, die nach derselben ID suchen. Das möchte ich möglichst vermeiden. Was ist der beste Weg, dieses Szenario zu testen?

Wenn es darauf ankommt, ist die Anwendung .NET 4 und Datenbank 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

Wenn Sie auf SQL Server gehen für ihre spezifische Ausstrahlung -Warum kann nicht zu überprüfen Sie generieren sie dort auf den ersten Platz? – YavgenyP

+0

Können Sie anstelle einer Zufallszahl stattdessen auch die Spalte "Identity" verwenden? – Matthew

+2

Warum nicht einfach eine GUID verwenden? Ich bin kein großer Fan davon, ein Rad neu zu erschaffen. –

Antwort

10

Sie sind direkt in Ihrem Anliegen: Sie sollten die Erstellung Ihrer Random Instanz aus Ihrer Methode Körper bewegen - sonst Sie werden mit dem gleichen Wert viele Male erneut seed, was zu der gleichen Zahlenfolge führt.

Auch Sie sind irgendwie neu das Rad: der Standardkonstruktor der Random Klasse verwendet bereits die aktuelle Uhrzeit als Standard-Seed.

Die Frage ist, warum vermeiden Sie nicht all dies und verwenden Sie einfach eine automatisch generierte Guid auf der Datenbankseite?

+0

Die ID wird im System eines externen Anbieters verwendet und hat bestimmte Formatierungskriterien: 25 Zeichen lang, vorangestellt mit 3 Buchstaben und Datum im Format JJJJMMTT. Ich kann nur wirklich mit den restlichen 14 Charakteren spielen. – Brian

+1

Oh und in Bezug auf die Standard-Random-Konstruktor, danke für die Info. Wusste nicht, dass es standardmäßig Tick-Ticks verwendet - ich werde das in meinem Code unbedingt aktualisieren! – Brian

+1

Ich landete 'Random' außerhalb meiner Schleife, so dass ich es in' GenerateUniqueDelId (Zufallsgenerator) 'übergeben kann. – Brian

6

Zitiert Jon Skeet

Wenn Sie das Wort „random“ in einem Frage-Titel auf Stack-Überlauf sehen Sie fast garantieren, wird es das gleiche Grundproblem wie unzählige ähnliche Fragen sein. Dieser Artikel untersucht, warum Zufälligkeit so viele Probleme verursacht und wie man sie anspricht.

Überprüfen seinen Artikels über Zufallszahlengeneratoren

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

im Grunde seine Lösung wie folgt aussieht:

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

Danke, ich werde diesen Artikel definitiv lesen. – Brian

+0

Ich habe immer noch Duplikate mit Environment.TickCount als Seed erhalten. Am Ende habe ich (int) DateTime.UtcNow.Ticks benutzt und noch keine doppelten Ergebnisse erhalten. –

+0

@JoshDeLong - Das ist der Spaß am Zufall; Es verspricht nicht, niemals Duplikate zu liefern :) –