2010-07-19 144 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

相關問題