我们有一个应用程序可以为我们的一项服务生成模拟数据以用于测试目的。每个数据项都有一个唯一的 Guid。然而,当我们对模拟器进行一些小的代码更改后运行测试时,它生成的所有对象都具有相同的 Guid。
创建了一个数据对象,然后是一个 for 循环,其中修改了该对象的属性,包括一个新的唯一 Guid,并通过远程处理(可序列化,而不是按引用封送,如果您是这样的话)将其发送到服务正在思考),循环并再次执行,等等。
如果我们在循环中放置一个小的 Thread.Sleep(...),它会生成唯一的 id。我认为这是一个转移注意力的事情。我创建了一个测试应用程序,它只是创建了一个又一个的 guid,并且没有得到任何重复。
我的理论是,IL 的优化方式导致了这种行为。关于我的理论就够了。你怎么认为?我愿意接受建议和测试方法。
更新:我的问题似乎有很多困惑,所以让我澄清一下。我不认为 NewGuid() 被破坏了。显然它有效。没关系!但某个地方有一个错误,会导致 NewGuid() 执行以下任一操作:
1)在我的循环中仅被调用一次
2)在我的循环中每次都被调用但只分配一次
3)还有一些我没想到的事情
这个错误可能在我的代码中(最有可能)或在某个地方的优化中。
所以重申我的问题,我应该如何调试这个场景?
(感谢您的精彩讨论,这确实帮助我澄清了我心中的问题)
更新#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
}
Submit 是否执行异步调用,或者票证对象是否在任何阶段进入另一个线程。
在代码示例中,您重用了同一个对象。如果“提交”在短暂延迟后在后台线程中发送票证(并且不获取副本),会怎么样?当您更改 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));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)