我知道 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?
}
如何在连接未打开或生成某种错误时向用户显示信息?
我知道 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?
}
如何在连接未打开或生成某种错误时向用户显示信息?
using
块中的代码并没有什么特别之处 - 只需使用try.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
块并自行确保正确的释放(正如Adam在他的答案中建议的那样)。using
并没有为catch
提供任何后门。
只需手动展开它(在我看来,使用try/catch没有意义):
SqlConnection conn = null;
try
{
conn = new SqlConnection("");
}
catch ...
{
}
finally
{
if (conn != null)
conn.Dispose();
}
我更喜欢这种方法,而不是将using
包装在try-catch
中或者大部分时间内将try-catch
嵌入到using
中,以避免编译后代码出现嵌套的try-catch
。然而,如果你只需要覆盖一个大段代码中的非常小的子集,那么我会更加精细并将其嵌入。
using
不提供任何支持,你必须回到 try/catch。 - Adam Houldsworthusing
。 - Adam Houldsworthclass 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/catch中时,using()块确实会保证调用Dispose。但是,如果您的using块内部的非托管代码抛出异常,using()将只吞掉它,而不会到达catch块。使用try/catch在using()块内部,跳过using()并进行try/catch/finally,或者使用奇怪的"using() try"语法与catch块(这会让中级程序员感到困惑,因为它们会留下奇数个括号)。
你不要在 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语句中使用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 的内存也不会被回收(或者最多会进入第二代 GC 集合)。
而在示例2中,catch 块位于 using 语句内部。这意味着执行将到达 using 块的末尾。因此,您的对象将被处理并且您不必担心内存泄漏(损坏)。
finally
块释放,并且异常将由外部的catch
块处理。在第二种情况下,异常将由内部的catch
块处理,而using
的隐式finally
将稍后对其进行处理和释放。因此,唯一的区别在于第二个示例中的catch
块仍然可以访问该对象,因此您仍然可以使用它来处理异常。在第一个示例中,在catch
块中不再可用该对象。没有其他差异。 - JotaBe