2012-06-05 25 views
5

我使用當前時鐘滴答作爲隨機數生成的種子。隨機數在僞GUID中使用,並且數據庫中的檢查將確保它在返回之前不存在。平均而言,這個方法在整個生命週期中將被連續調用10次左右。使用時鐘滴答作爲隨機數種子

我的問題是,一個相同的數字可能會背靠背生成,導致對我的數據庫進行多次不必要的遞歸調用以檢查相同的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() 
+3

如果你打算到SQL Server,以檢查他們的出射度 - 爲什麼斜面你在第一時間在那裏生成它們? – YavgenyP

+0

作爲使用隨機數的替代方法,您可以使用「Identity」列嗎? – Matthew

+2

爲什麼不直接使用GUID。我不是重新創造輪子的忠實粉絲。 –

回答

10

你是對你的關心:你應該將你的Random實例的創建出你的方法體的 - 否則您將重新種子以相同的值多次導致相同的數字序列。

此外,你有點重新發明輪子:Random類的默認構造函數已經使用當前時鐘時間作爲默認種子。

問題是爲什麼你不避免所有這一切,只是在數據庫端使用自動生成的Guid?

+0

該ID在外部供應商的系統中使用,並且具有特定的格式標準:長度爲25個字符,前綴爲3個字母字符,日期格式爲yyyyMMdd。我只能真正玩剩下的14個人物。 – Brian

+1

哦,關於默認的Random構造函數,謝謝你的信息。不知道它默認使用時鐘滴答 - 我一定會在我的代碼中更新它! – Brian

+1

我最終將'Random'移動到了我的循環之外,因此我可以將它傳遞給'GenerateUniqueDelId(Random generator)'。 – Brian

6

報價喬恩斯基特

當你在堆棧溢出問題的標題看到「隨機」你幾乎可以保證這將是無數類似的問題同樣的根本問題。本文將介紹爲什麼隨機性會導致如此多的問題,以及如何解決這些問題。

檢查他的文章對隨機數生成

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

謝謝,我一定會讀這篇文章。 – Brian

+0

我仍然收到使用Environment.TickCount作爲種子的重複項。我結束了使用(int)DateTime.UtcNow.Ticks,並沒有收到任何重複的結果呢。 –

+0

@JoshDeLong - 這是隨機性的樂趣;它不承諾永不交付重複:) –