2012-03-06 58 views
1

據我所知,使用像try/catch/finally這樣的工程,所以我期望如果在using語句中發生異常,它會被捕獲(這有點奇怪,因爲那也意味着異常是默默吃了)。 using語句應該捕獲異常並調用Dispose方法,但是,這種情況不會發生。我已經設計了一個簡單的測試來演示這個問題。爲什麼在應該像try/catch/finally那樣運行時拋出異常?

這裏是我強迫異常using語句裏面發生:

using (TcpClient client = new TcpClient()) 
{ 
    // Why does this throw when the using statement is supposed to be a try/catch/finally? 
    client.Connect(null); 
} 

一個例外是拋出由client.Connect()(這意味着它沒有被使用的語句或捕獲,它正在重新拋出) :

System.ArgumentNullException: Value cannot be null. 
Parameter name: remoteEP 
    at System.Net.Sockets.TcpClient.Connect(IPEndPoint remoteEP) 
    at DotNETSandbox.Program.Main(String[] args) in C:\path\to\Sandbox\Program.cs:line 42 

a Microsoft article on the topic,using語句可能如果Dispose方法拋出拋出。

然而,當我正在關注的使用模式,顯而易見的是,Dispose方法不拋出:

TcpClient c2 = new TcpClient(); 
try 
{ 
    c2.Connect(null);    
} 
catch (Exception e) 
{ 
    // We caught the null ref exception 
    try 
    { 
     // Try to dispose: works fine, does not throw! 
     ((IDisposable)c2).Dispose(); 
    } 
    catch (Exception e2) 
    { 
     Console.WriteLine(e2.ToString()); 
    } 
    Console.WriteLine(e.ToString()); 
} 

我有點困惑,因爲我期待using表現得像一試/抓住。有誰能解釋爲什麼會發生這種情況嗎?

+3

,終於阻止,終於不是試試抓住。異常仍會拋出使用塊。 – 2012-03-06 19:44:26

+3

爲什麼_what_發生?你是否期望'using'語句默默地吃掉異常? – SLaks 2012-03-06 19:45:40

+0

@SLaks由於某種原因,我留下的印象是「使用」有一個聲明,我從來沒有真正投入過多的想法,直到現在。我總是抓住例外,它從來沒有真正擔心過我,但在閱讀文章後,我意識到我錯過了一些東西。 – Kiril 2012-03-06 19:56:33

回答

8

使用是

try 
{ 
} 
finally 
{ 
} 

有沒有趕上!

在你沒有捕獲異常.NET

..

這隻要你離開這個範圍調用Dispose方法,它只是一種機制。就這樣。

p.s. :「我怎麼知道我的物品是否可以使用?」

回答:別擔心 - 編譯時您會看到錯誤。

+0

我明白了......好的,現在有道理! – Kiril 2012-03-06 19:51:35

+0

另外,如果一個對象實現了IDisposable接口,你可以判斷一個對象是否可以使用 – 2012-03-06 19:57:45

5

using是更多的try/finally沒有catch

控制不能離開塊,沒有你使用的對象被處置,這就是它
從塊中拋出的任何異常都將(正常處理後)(在處置後)傳遞。

編輯:在我自己的答案採摘尼特,在實現IEnumerable和產生出using特殊情況下,你可以說離開塊沒有Dispose()被調用,但是當繼續枚舉你會最後再次回到裏面。

3

因爲using的行爲不像try/catch/finally。它表現得像一個嘗試/最後一樣。

你的第一個例子,雖然它拋出一個異常,但仍然會正確配置TcpClient。

2

使用語句的行爲就像try,finally塊,而不是try,catch,finally塊。

異常仍會拋出使用塊。

0

正如很多人所說的使用聲明沒有捕獲異常。但我可以從這篇文章中看到你的困惑。

它說,如果 Dispose()失敗它可以隱藏在使用塊內引發的任何錯誤。

因爲的Dispose()一個 「最後」 塊內發生時,ApplicationException的是從未見過的使用塊外,如果的Dispose() using語句像一個嘗試失敗

相關問題