2012-03-06 62 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语句像一个尝试失败

相关问题