C# 在 Using 语句中捕获异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10193674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Catching Exception inside Using statement
提问by RG-3
I know that Usingstatement disposes out the object that is being created. Like if I wanted to do something like this:
我知道Using语句会处理正在创建的对象。就像我想做这样的事情:
Using(SqlConnection conn = new SqlConnection(connString))
{
//some code
//How to show the users if conn is not opened up or generated some kind of error?
}
How to show the users if conn is not opened up or generated some kind of error?
如果 conn 未打开或产生某种错误,如何向用户显示?
回答by Adam Houldsworth
usingdoesn't offer any backdoor into the catch.
using不提供任何后门进入catch.
Simply expand it manually (no point in having the try/catch inside the using IMO):
只需手动扩展它(在使用 IMO 中使用 try/catch 毫无意义):
SqlConnection conn = null;
try
{
conn = new SqlConnection("");
}
catch ...
{
}
finally
{
if (conn != null)
conn.Dispose();
}
I favour this over wrapping the usingin a try-catchor embedding a try-catchin the usingmost of the time to avoid having the code end up with a nested try-catchonce compiled. If you only need to cover a very small subset of a large piece of code within a using, however, I'd be more granular and embed it.
在大多数情况下,我更喜欢将 a包装using在 atry-catch或嵌入 atry-catch中,using以避免代码最终以嵌套的方式try-catch编译。但是,如果您只需要在一个using.
回答by marc_s
There's nothing special about code written inside a usingblock - just use a try.catchto handle exceptions:
写在using块内的代码没有什么特别之处——只需使用 atry.catch来处理异常:
using(SqlConnection conn = new SqlConnection(connString))
{
try
{
conn.Open();
// do more stuff here......
}
catch(SqlException sqlEx)
{
// log error and possibly show to user in a MessageBox or something else
}
}
The using(...) { ... }block itself is designed onlyto ensure that the resource / object it "encapsulates" is properly disposed of when it's no longer needed. There's is nothing you can do with the usingstatement itself to make it handle errors.
该using(...) { ... }块本身的设计只保证了资源/对象为“包囊”妥善处理时,它不再需要的。您无法对using语句本身做任何事情来使其处理错误。
So if you expect that just creating the object could fail, then you'd have to put the entire usingblock inside the try ... catchblock , or fall back to a try ... catch ... finallyblock and ensure proper disposal yourself (as Adam suggested in his answer).
因此,如果您预计仅创建对象可能会失败,那么您必须将整个using块放入try ... catch块中,或者退回到try ... catch ... finally块并确保自己正确处理(正如亚当在他的回答中所建议的那样)。
回答by Matten
Thats just the same way you would do it without.
这与您在没有的情况下做的方式相同。
using(SqlConnection conn = new SqlConnection(connString))
{
try{
//some code
}
catch(SqlException e)
MessageBox.Show(e.Message);
}
回答by Widor
Just in the normal way:
只是以正常方式:
Either
任何一个
try
{
using(SqlConnection conn = new SqlConnection(connString))
{
//some code
}
}
catch (Exception exc)
{
//handle error
}
or
或者
using(SqlConnection conn = new SqlConnection(connString))
{
try
{
//some code
}
catch (Exception exc)
{
//handle error
}
}
回答by Jodrell
You don't do it inside the using
你不要在里面做 using
try
{
using(SqlConnection conn = new SqlConnection(connString))
{
// Some code for when "conn" is succesfully instantiated
}
}
catch (SomeSpecificConnectionInstantiationException ex)
{
// Use ex to handle a bizarre instantiation exception?
}
回答by Sandeep
class SqlConnection
{
using(sqlConnection)
{
}
}
class Consumer
{
try
{
}
catch(SqlException)
{
}
}
It is up to the consumer of the class to decide what to do with the exception.
由类的使用者决定如何处理异常。
回答by Joel Coehoorn
As other answers have stated, just add a normal try/catch.
正如其他答案所述,只需添加一个普通的 try/catch。
However, I would add that this is the wrongplace to put that try/catch, especiallyif your goal is "show the users" a message. Let the exception happen at this level, and allow it to bubble up the stack to code that's in a better position to know how to respond to it.
但是,我要补充一点,这是放置 try/catch的错误位置,尤其是当您的目标是“向用户显示”消息时。让异常发生在这个级别,并允许它在堆栈中冒泡到更适合知道如何响应它的代码。
In other words, leave your code sample as it is. Don't add anything new... to that method. But perhaps the code that calls this method should be thinking about how to handle an exception ... any exception... from the database.
换句话说,让您的代码示例保持原样。不要添加任何新的东西......到那个方法。但也许调用此方法的代码应该考虑如何处理来自数据库的异常……任何异常……。
回答by Raja Naeem
It is a good practice to use the try{}catch(){} inside the using statement if you want to catch an exception thrown by the code inside the using block. Now, consider the following two examples - that explains why try-catch block inside the using statement is a good practice.
如果您想捕获 using 块中的代码抛出的异常,最好在 using 语句中使用 try{}catch(){}。现在,考虑以下两个示例 - 这解释了为什么 using 语句中的 try-catch 块是一个很好的做法。
Example 1
示例 1
try{
using(SomeObject so = new SomeObject){
// Perform some tasks
}
}catch(SomeException objSomeException){
// Perform some actions, if exception occurs
}
Example 2
示例 2
using(SomeObject so = new SomeObject){
try{
// Perform some tasks
}catch(SomeException objSomeException){
// Perform some actions, if exception occurs
}
}
Now, if an exception occurs while performing some tasks inside the using statement, will both example have the same results. The simple answer is no, reason???
现在,如果在 using 语句中执行某些任务时发生异常,两个示例将具有相同的结果。简单的答案是否定的,原因???
When an exception occurs in the example 1, it is caught by the catch block - without reaching the end of the using block. Therefore, the someObject in example 1 will not get disposed properly. Even if CLR is generous (which you should not count on) - the memory used by the someObject in the example 1 will not be recovered (or maximum it will end up in Generation 2 GC collection).
当示例 1 中发生异常时,它会被 catch 块捕获 - 不会到达 using 块的末尾。因此,示例 1 中的 someObject 将不会被正确处理。即使 CLR 很慷慨(您不应该指望这一点) - 示例 1 中 someObject 使用的内存也不会被恢复(或者最多将在第 2 代 GC 收集中结束)。
Where in case of the example 2, the catch block is inside the using statement. That means that the execution will reach the end of the using block. Therefore, your object will be disposed and you won't have to worry about the memory leakage (spoilage,
在示例 2 的情况下,catch 块位于 using 语句内。这意味着执行将到达 using 块的末尾。因此,您的对象将被处理,您不必担心内存泄漏(损坏、
回答by MiddleAgedMutantNinjaProgrammer
When you embed the using() block inside a try/catch, the using() block will indeed guarantee that Dispose is called. However, if non-managed code anywhere within your using block throws an exception, using() will just eat it and it won't reach your catch. Use try/catch inside the using() block, skip using() and do a try/catch/finally, or use the odd "using() try" syntax with a catch block (which leaves you with an odd number of brackets and is likely to confuse the heck out of mid-level programmers who later encounter it.
当您在 try/catch 中嵌入 using() 块时, using() 块确实会保证调用 Dispose。但是,如果 using 块中任何地方的非托管代码抛出异常, using() 只会吃掉它并且不会到达您的捕获。在 using() 块中使用 try/catch,跳过 using() 并执行 try/catch/finally,或使用带有 catch 块的奇数“using() try”语法(这会给您留下奇数个括号和很可能会让后来遇到它的中级程序员感到困惑。

