2012-09-11 30 views
0

我有一個C#Windows用戶界面程序,其中Window1 : Window的構造函數啓動了一個異步套接字服務器,該套接字服務器將while (true) { /* BeginAccept */ }並將數據流式傳輸到使用BeginSendEndSend連接的任何客戶端。爲什麼在異步C#套接字代碼中的異常終止我的程序沒有堆棧跟蹤?

如果一個客戶端強制掛斷Socket.EndSend拋出異常(有點令人驚訝的ObjectDisposedException代替SocketException,但不管)。

這個例外終止我的整個程序(關閉窗口)但不打印堆棧跟蹤!

相反,我只得到的輸出繼電器面板無辜

A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll 

消息。

如果有異常這樣沉默這樣但仍然崩潰我的程序沒有堆棧跟蹤,我該如何找到異常被拋出的位置?

回答

2

那麼,這取決於你使用的是什麼版本的.NET。但是,這通常會記錄下來。

如果您不希望發生這種情況,請在線程入口點使用頂級異常處理程序,然後「吞下」異常 - 在退出線程之前將其記錄或執行任何其他操作。

就像BeginSend這樣的方法而言,BeginSend(或BeginAccept就此而言)的方法實際上是線程入口點。例如

listener.BeginAcceptTcpClient(OnAccept, null); 
//... 

private static void OnAccept(IAsyncResult ar) 
{ 
    try { 
     var tcpClient = listener.EndAcceptTcpClient(ar); 
     //... 
    } catch(Exception ex) 
    { 
     Dump(ex); 
     return; 
    } 
} 
+0

我首先想到這個固定的,但它並不:即使我抓住周圍的所有異常都是'BeginSend'和'EndSend',殺了客戶端仍然有時會殺死我的程序(這個時間實際上是一個' SocketException'):/ – nh2

+0

嗯,當然:我有一個老的'BeginReceive' /'EndReceive',但是它並沒有在'try'塊中保護。另外,在'Release'模式下運行實際上會將堆棧跟蹤隱藏到停止我的程序的異常。 – nh2

+0

@ nh2我剛剛提到,任何其他開始/結束將需要有相同的嘗試/捕獲... –