当前位置:  开发笔记 > 编程语言 > 正文

Guid.NewGuid()返回重复?

如何解决《Guid.NewGuid()返回重复?》经验,为你挑选了2个好方法。

我们有一个应用程序为我们的某个服务生成模拟数据以进行测试.每个数据项都有一个唯一的Guid.但是,当我们在对模拟器进行一些次要代码更改后运行测试时,它生成的所有对象都具有相同的Guid.

创建了一个数据对象,然后是一个for循环,其中对象的属性被修改,包括一个新的唯一Guid,它通过远程处理发送到服务(可序列化,而不是编组,如果这就是你'思考),循环再做,等等.

如果我们在循环内部放置一个小的Thread.Sleep(...),它会生成唯一的id.我认为这是一个红鲱鱼.我创建了一个测试应用程序,它刚刚创建了一个guid,并没有得到一个副本.

我的理论是IL的优化方式导致了这种行为.但足够我的理论.你怎么看?我愿意接受测试的建议和方法.

更新:我的问题似乎有很多混乱,所以让我澄清一下.我不认为NewGuid()被破坏了.显然它有效.没关系!但是某处有一个bug会导致NewGuid():1)在我的循环中只调用一次2)在我的循环中每次调用但只分配一次3)其他我没想过的东西

这个bug可能出现在我的代码中(可能是MOST)或者在某个地方进行优化.

所以重申我的问题,我应该如何调试这个场景?

(谢谢你的精彩讨论,这真的帮助我澄清了我心中的问题)

更新#2:我想发布一个显示问题的例子,但那是我问题的一部分.我不能在整套应用程序(客户端和服务器)之外复制它.

这是一个相关的片段:

OrderTicket ticket = new OrderTicket(... );

for( int i = 0; i < _numOrders; i++ )
{
    ticket.CacheId = Guid.NewGuid();
    Submit( ticket );  // note that this simply makes a remoting call
}

Robert Wagne.. 21

Submit是否执行异步调用,或者ticket对象是否在任何阶段进入另一个线程.

在代码示例中,您将重用相同的对象.如果提交在短暂延迟后在后台线程中发送票证(并且不复制),该怎么办?当您更改CacheId时,实际上正在更新所有待处理的提交.这也解释了为什么Thread.Sleep修复了这个问题.试试这个:

for( int i = 0; i < _numOrders; i++ )
{
    OrderTicket ticket = new OrderTicket(... );
    ticket.CacheId = Guid.NewGuid();
    Submit( ticket );  // note that this simply makes a remoting call
}

如果由于某种原因这是不可能的,试试这个,看看它们是否仍然相同:

ticket.CacheId = new Guid("00000000-0000-0000-0000-" + 
     string.Format("{0:000000000000}", i));

@dviljoen:看起来我毕竟赢了那个赌注.:) (3认同)


MusiGenesis.. 6

成千上万的开发人员在.NET中使用Guids.如果Guid.NewGuid()有任何倾向于"卡住"一个值,很久以前就会遇到这个问题.

次要代码更改是这里的罪魁祸首.事实上,Thread.Sleep(不像红色鲱鱼比在阳光下腐烂的鱼)"修复"你的问题表明你的属性是以某种奇怪的方式设置的,直到循环停止阻塞才能生效(或者通过结束或通过Thread.Sleep).我甚至愿意打赌,"小改动"是从一个单独的线程重置所有属性.

如果您发布了一些示例代码,那将有所帮助.



1> Robert Wagne..:

Submit是否执行异步调用,或者ticket对象是否在任何阶段进入另一个线程.

在代码示例中,您将重用相同的对象.如果提交在短暂延迟后在后台线程中发送票证(并且不复制),该怎么办?当您更改CacheId时,实际上正在更新所有待处理的提交.这也解释了为什么Thread.Sleep修复了这个问题.试试这个:

for( int i = 0; i < _numOrders; i++ )
{
    OrderTicket ticket = new OrderTicket(... );
    ticket.CacheId = Guid.NewGuid();
    Submit( ticket );  // note that this simply makes a remoting call
}

如果由于某种原因这是不可能的,试试这个,看看它们是否仍然相同:

ticket.CacheId = new Guid("00000000-0000-0000-0000-" + 
     string.Format("{0:000000000000}", i));


@dviljoen:看起来我毕竟赢了那个赌注.:)

2> MusiGenesis..:

成千上万的开发人员在.NET中使用Guids.如果Guid.NewGuid()有任何倾向于"卡住"一个值,很久以前就会遇到这个问题.

次要代码更改是这里的罪魁祸首.事实上,Thread.Sleep(不像红色鲱鱼比在阳光下腐烂的鱼)"修复"你的问题表明你的属性是以某种奇怪的方式设置的,直到循环停止阻塞才能生效(或者通过结束或通过Thread.Sleep).我甚至愿意打赌,"小改动"是从一个单独的线程重置所有属性.

如果您发布了一些示例代码,那将有所帮助.

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有