我知道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?
}
如果 conn 未打开或产生某种错误,如何向用户显示?
编写在块内的代码没有什么特别之处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
}
}
using(...) { ... }
块本身的设计只是为了确保它“封装”的资源/对象在不再需要时被正确处理。您无法对using
语句本身做任何事情来使其处理错误。
因此,如果您希望仅创建对象可能会失败,那么您必须将整个using
块放入try ... catch
块中,或者退回到try ... catch ... finally
块并确保自己正确处理(正如亚当在他的回答中所建议的那样)。
using
不提供任何后门进入catch
.
只需手动扩展它(在使用 IMO 中使用 try/catch 没有意义):
SqlConnection conn = null;
try
{
conn = new SqlConnection("");
}
catch ...
{
}
finally
{
if (conn != null)
conn.Dispose();
}
在大多数情况下,我更喜欢using
在 a中包装try-catch
或嵌入 a以避免代码在编译后以嵌套的形式结束。但是,如果您只需要在.try-catch
using
try-catch
using
class SqlConnection
{
using(sqlConnection)
{
}
}
class Consumer
{
try
{
}
catch(SqlException)
{
}
}
由类的使用者决定如何处理异常。
正如其他答案所述,只需添加一个正常的 try/catch 即可。
但是,我要补充一点,这是放置 try/catch的错误位置,特别是如果您的目标是“向用户展示”一条消息。让异常发生在这个级别,并允许它在堆栈中冒泡到处于更好位置以知道如何响应它的代码。
换句话说,让您的代码示例保持原样。不要在该方法中添加任何新内容。但也许调用此方法的代码应该考虑如何处理数据库中的异常......任何异常。
只是以正常方式:
任何一个
try
{
using(SqlConnection conn = new SqlConnection(connString))
{
//some code
}
}
catch (Exception exc)
{
//handle error
}
或者
using(SqlConnection conn = new SqlConnection(connString))
{
try
{
//some code
}
catch (Exception exc)
{
//handle error
}
}
这与没有它的方式相同。
using(SqlConnection conn = new SqlConnection(connString))
{
try{
//some code
}
catch(SqlException e)
MessageBox.Show(e.Message);
}
你不要在里面做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?
}
当你在 try/catch 中嵌入 using() 块时, using() 块确实会保证 Dispose 被调用。但是,如果您 using 块中任何地方的非托管代码抛出异常, using() 只会吃掉它,它不会到达您的捕获。在 using() 块中使用 try/catch,跳过 using() 并执行 try/catch/finally,或者使用带有 catch 块的奇数“using() try”语法(这会留下奇数个括号和可能会混淆后来遇到它的中级程序员。
如果要捕获 using 块内的代码引发的异常,最好在 using 语句中使用 try{}catch(){}。现在,考虑以下两个示例 - 这解释了为什么在 using 语句中使用 try-catch 块是一个好习惯。
示例 1
try{
using(SomeObject so = new SomeObject){
// Perform some tasks
}
}catch(SomeException objSomeException){
// Perform some actions, if exception occurs
}
示例 2
using(SomeObject so = new SomeObject){
try{
// Perform some tasks
}catch(SomeException objSomeException){
// Perform some actions, if exception occurs
}
}
现在,如果在 using 语句中执行某些任务时发生异常,两个示例将具有相同的结果。简单的答案是否定的,原因???
当示例 1 中发生异常时,它会被 catch 块捕获 - 不会到达 using 块的末尾。因此,示例 1 中的 someObject 将无法正确处理。即使 CLR 是慷慨的(你不应该指望它) - 示例 1 中 someObject 使用的内存也不会被回收(或最大值将在第 2 代 GC 收集中结束)。
在示例 2 的情况下,catch 块位于 using 语句内。这意味着执行将到达 using 块的末尾。因此,您的对象将被丢弃,您不必担心内存泄漏(损坏,