我们有一个应用程序为我们的某个服务生成模拟数据以进行测试.每个数据项都有一个唯一的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).我甚至愿意打赌,"小改动"是从一个单独的线程重置所有属性.
如果您发布了一些示例代码,那将有所帮助.
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));
成千上万的开发人员在.NET中使用Guids.如果Guid.NewGuid()有任何倾向于"卡住"一个值,很久以前就会遇到这个问题.
次要代码更改是这里的罪魁祸首.事实上,Thread.Sleep(不像红色鲱鱼比在阳光下腐烂的鱼)"修复"你的问题表明你的属性是以某种奇怪的方式设置的,直到循环停止阻塞才能生效(或者通过结束或通过Thread.Sleep).我甚至愿意打赌,"小改动"是从一个单独的线程重置所有属性.
如果您发布了一些示例代码,那将有所帮助.