2010-07-19 171 views
1

我有一个奇怪的问题。我有一个单元测试,一直停留在运行模式下。当我在调试中运行相同的测试时,没有断点,测试通过每次。单元测试通过调试,但运行时挂起

基本上,它是一个套接字连接测试。我首先断开一个套接字,然后尝试重新连接,并试图检查重新连接是否成功。

在连接代码的某处,我检查是否有套接字异常。发生这种情况时,用户会在对话框中看到一些选择,而连接代码通过AutoResetEvent挂起,等待一个决定。

这是AutoResetEvent挂起系统。它必须由单元测试中的代码提供。 但我的问题是,这是如何通过调试模式?有没有什么特别的调试模式,AutoResetEvents是由Visual Studio自动设置的?

编辑

这确实是一个竞争状态。我在断开连接代码后在代码中添加了延迟,现在它可以工作。但它仍然让我感到奇怪的是,有一个竞争条件的开始。让我通过粘贴一些代码来详细说明。

这是测试代码:

MySystem.FindEquipment(new List<string>(1) { "192.1.1.243:28000" }); 
MySystem.ConstructSystem(); 
MySystem.IsConstructedFlag.WaitOne(); 
Assert.AreEqual(1, MySystem.CommunicationController.HardwareIPList.Count); 

PFFrame frame1 = MySystem.Frames["0.x.x"]; 

Assert.IsTrue(frame1.Disconnect()); 
Thread.Sleep(100); 
Assert.IsTrue(frame1.Connect()); 

这令我的原因,是我等待的diconnect代码的返回,调用connect代码之前。断开代码的最后一部分是这样的:

lclSocket.Shutdown(SocketShutdown.Both); 
lclSocket.Close(); 
OnSocketDisconnected(new PFSocketConnectionEventArgs(ipEp)); 
return true; 

难道是因为Socket.Shutdown(),和/或Socket.Close()方法来运行它的主题?因此,即使我从我的断开连接代码返回值,套接字实际上并没有真正断开连接?

+1

我从来没有使用过.NET Socket API,所以我在这里帮不了你。我假设lclSocket是一个System.Net.Sockets.Socket类实例?看看这些文档,我可以看到在多线程环境中运行时有各种异步方法。您应该通过注释代码来退出代码更改,直到代码在调试和发布中运行。然后仔细阅读文档,确保您使用了正确的方法。同时断言一切。然后逐步添加一小段代码,直到您缩小错误。 – 2010-07-19 16:17:02

回答

2

这听起来像是一种竞赛条件。调试代码通常会在“引擎盖下”运行很多额外的东西,这种时间差异可能会导致您的测试关闭。

当然,没有看到代码,我们真的帮不了你。

+0

这确实是一个竞赛条件..但我还有一个问题,请看我编辑。 – sbenderli 2010-07-19 15:13:28

2

最有可能是因为穿线比赛。它们对时序非常敏感,并且Debug版本中的时序将有所不同。您可以使用像CHESS这样的工具来锻炼这样的错误。

但是先使用工具+附加到过程。调试+全部中断,调试+ Windows +线程并查看线程调用堆栈。你可能会看到比赛或僵局的原因。

1

曾经有一个类似的问题,我比较了两个日期,并且期望一个日期在另一个日期之后,但由于它的执行速度很快,他们收到了相同的时间戳。

0

此测试告诉您,您的代码与您正在使用的套接字库没有正确隔离。您正在测试的代码不应该依赖于此库中的某些工件。您需要在采用工件的套接字库之间添加一个抽象为acoount。

我这样说的原因是,如果socket实际上断开了123,251次< 100 mSecs,但是123,252次断开连接需要101 mSecs。

我强烈建议您几乎所有的单元测试代码都不使用线程。我将单元测试中的任何类型的调用作为代码异味来看待。通常我希望看到线程问题出现在集成级别。

+0

我知道,我想添加Thread.Sleep为了确保我试图在完全断开连接后重新连接。在我的断开连接代码中,我先调用Shutdown,然后调用Close。不过,我还不知道有什么办法来检查Socket是否完全断开连接,并准备进行另一次连接尝试。有任何想法吗? – sbenderli 2010-07-19 18:11:16

相关问题