C# 生成的顺序guid有时不是顺序的

C# 生成的顺序guid有时不是顺序的,c#,guid,sequential,newsequentialid,C#,Guid,Sequential,Newsequentialid,我有一个C#应用程序,它为我插入到表中的每一行生成一个顺序GUID。我希望插入的guid是连续的,但有时它们会(分块)中断序列 例如: 这些guid按插入顺序显示 为什么要用如此大的顺序中断来创建这些“顺序”guid? 用于生成顺序GUID的代码: class NativeMethods { [DllImport("rpcrt4.dll", SetLastError = true)] public static extern int UuidCreateSequential(

我有一个C#应用程序,它为我插入到表中的每一行生成一个顺序GUID。我希望插入的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:

系统重新启动时,
NewSequentialId()
将重新启动。看

创建大于以前由生成的任何GUID的GUID 自Windows启动后,此函数在指定的计算机上运行。之后 重新启动Windows时,GUID可以从较低的范围重新启动,但 它仍然是全球独一无二的。当GUID列用作行时 标识符,使用NEWSEQUENTIALID可能比使用NEWID更快 功能。这是因为NEWID函数会导致随机活动 并且使用更少的缓存数据页。使用NEWSEQUENTIALID也有助于 完全填充数据和索引页


我认为问题在于你假设“顺序”意味着“一次递增”。尽管您的示例表明有时会发生这种情况,但文档中并没有实际保证它会发生。我们可能会争论“序列”的定义,或者可能这个函数的命名很差,甚至是错误的,但最终,根据文档,它似乎完全按照定义工作:

创建大于此函数以前生成的任何GUID的GUID

对于那些对“顺序GUID”的一般概念有疑问的人,请使用“顺序”的定义,即“遵循逻辑顺序”,并尝试记住Melissa病毒。这是:

出于安全原因,修改了UuidCreate,使其不再使用机器的MAC地址生成UUID。UuidCreateSequential的引入允许使用机器以太网卡的MAC地址创建UUID

因此,“序列”是基于MAC地址的GUID


回到OP的问题,我对为什么每次都没有增加一个GUI的最佳猜测是,您可能不是唯一一个调用此函数的人。这是Windows的核心功能,肯定会有其他组件、程序、服务等使用它。

GUID是唯一的编号。不多也不少。虽然可以使用不同的算法来生成它们,但不应该依赖于特定实现的特定属性。将
GUID
作为GUID,不再使用。如果您需要一个递增的数字,那么就获取一个数字并递增它,而不是使用GUID,它只是生成唯一数字的一种表示方式。我从来没有听说过顺序GUID,但这似乎完全错误。这是你编的吗?GUID本质上是唯一的,您无法控制它的生成方式。如果您知道将生成的下一个GUID是什么(因为它是上一个GUID的下一个),那么它就不是唯一的,因为其他人可以从相同的起始值开始执行相同的操作。这有什么关系?只要它们仍然处于有序状态,它就仍然可以工作,并且索引不必重新排序。这并不是说它们将耗尽值:)它似乎使用系统时间,这样我就可以看到时钟更新时有跳跃(大约每15毫秒)。依我看,顺序并不意味着连续。谢谢你的回答。我意识到这可能发生在Windows重新启动后。我的
CreateSequentialGuid()
方法在一个快速
for
循环中被调用,我的机器没有重新启动。这个答案是正确的,但我想补充一点,如果OP希望使用结果在SQL Server中插入行,她可能应该知道UuidCreateSequential对于SQL Server的排序顺序不是完全顺序的,需要执行一些字节填充:
Guid mySequentialGUID = CreateSequentialGuid();
string[] row = { item1,
                 item2,
                 item3,  
                 sourceText,
                 encoding.ToString(),
                 mySequentialGUID.ToString()
             };
var listViewItem = new ListViewItem(row);
myListView.Items.Add(listViewItem);