2017-01-27 61 views
3

我有一個C#應用程序,它爲插入到表中的每一行生成一個順序GUID。我期望插入的GUID是順序的,但有時他們打破序列(在塊)。生成的順序GUID有時不是連續的

實施例:

Break in sequence

這些GUID中示出了它們所插入的順序。

爲什麼這些'連續的'GUID是通過這麼大的序列中斷創建的?


代碼用來生成連續的GUID:在一個循環中用於插入新的GUID和信息表

class NativeMethods 
{ 
    [DllImport("rpcrt4.dll", SetLastError = true)] 
    public static extern int UuidCreateSequential(out Guid guid); 
} 

public static Guid CreateSequentialGuid() 
    { 
     const int RPC_S_OK = 0; 

     Guid guid; 
     int result = NativeMethods.UuidCreateSequential(out guid); 
     if (result == RPC_S_OK) 
      return guid; 
     else 
      return Guid.NewGuid(); //<--In debugging, this statement never runs. 
    } 

代碼:

Guid mySequentialGUID = CreateSequentialGuid(); 
string[] row = { item1, 
       item2, 
       item3, 
       sourceText, 
       encoding.ToString(), 
       mySequentialGUID.ToString() 
      }; 
var listViewItem = new ListViewItem(row); 
myListView.Items.Add(listViewItem); 

編輯: 請參閱此問題了解Sequential GUID:

+4

一個GUID存在是一個唯一的編號。沒有更多,不少。雖然可以使用不同的算法來生成它們,但不應該依賴特定實現的特定屬性。不要再用GUID作爲GUID。如果你需要一個遞增的數字,那麼*得到一個數字並遞增它*,而不是使用一個GUID,它只是*生成*唯一*數字的一種表示方法。 – Servy

+3

我從來沒有聽說過連續的GUID,但這似乎完全錯誤。你有這個嗎? GUID本質上是獨一無二的,你無法控制它是如何產生的。如果你知道將要生成的下一個GUID是什麼(因爲它與你的最後一個GUID是相鄰的),那麼它不是唯一的,因爲其他人可以以相同的起始值開始做同樣的事情。 –

+1

@ rory.ap我沒有組成一個連續的GUID。甚至有一種內置方法可以在Transact-SQL中創建順序GUIDS,稱爲NewSequentialID()。 https://msdn.microsoft.com/en-us/library/ms189786.aspx –

回答

4

我認爲問題在於你認爲「順序」的意思是「增加一」。儘管您的示例顯示出這種情況,但有時在文檔中沒有實際保證。我們可以說「序列」或者,也許這個功能是很差名爲甚至是錯誤的,但在這一天結束,根據這似乎是準確的工作100%的文件所界定的定義:

創建一個GUID比以前這個功能

產生對於具有「連續GUID」的總體思路有問題的人的任何GUID更大的使用「序列」這是關於「遵循邏輯順序」的定義並嘗試記住Melissa病毒。這是mildly document by this line

出於安全原因,UuidCreate被修改爲不再使用機器的MAC地址來生成UUID。引入了UuidCreateSequential以允許使用機器以太網卡的MAC地址創建UUID。

所以「序列」是基於MAC地址的GUID。

回到OP的問題,我最好猜測爲什麼你的GUID不會每次增加一個,這是一個簡單的事實,你可能不是唯一一個調用這個函數的人。這是一個核心的Windows功能,必然會有其他組件,程序,服務等使用它。

+0

這個答案是正確的,但我想補充一點,如果 OP希望使用結果在SQL Server中插入行,她 應該可能意識到UuidCreateSequential並不是完全順序的 關於SQL Server的排序順序,並需要執行一些 字節後綴:https://blogs.msdn.microsoft.com/dbrowne/2012/07/03/how-to-generate-sequential-guids-for-sql-server-in-net / – martin

1

NewSequentialId()開始在系統重新啓動時。請參閱here

創建一個GUID,該GUID比自從Windows啓動以來在指定的計算機上由 此函數以前生成的任何GUID大。在 重新啓動Windows之後,GUID可以從較低範圍重新開始,但 仍然是全局唯一的。當使用GUID列作爲行 標識符時,使用NEWSEQUENTIALID可能比使用NEWID 函數更快。這是因爲NEWID函數會導致隨機活動 並使用較少的緩存數據頁面。使用NEWSEQUENTIALID還有助於 完全填充數據和索引頁面。

+0

謝謝你的回答。我意識到這可能發生在Windows重新啓動後。我的'CreateSequentialGuid()'方法在一個快速'for'循環中被調用,並且我的機器沒有被重新啓動。 –