鉴于此代码:
using (var conn = new SqlConnection("..."))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "...";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// ...
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我习惯于为我的数据访问编写try/catch/finally块,但是,我正在接触"使用",这似乎是一种更简单的方法.但是,我试图弄清楚如何捕获可能发生的异常.
能否请您举例说明您如何捕捉异常?
编辑添加:
我被引导相信"使用"是我的try/catch/finally块的替代品.我知道使用不会捕获异常.那怎么替代呢?
Gre*_*ech 58
using不是为了捕捉例外; 它旨在为您提供一种简单的方法来包裹try/ finally围绕需要处理的对象.如果你需要捕获和处理异常,那么你需要将它扩展为一个完整的try/ catch/ finally或放置一个包含try/ catch围绕整个事物.
要回答你的编辑(是//?using的替代品),那么不,它不是.大多数情况下,当使用一次性资源时,您不会在那里处理异常,因为通常没有什么用处可以做.因此,它提供了一种方便的方法来确保资源被清理,而不管您尝试做什么工作.trycatchfinally
通常,处理可处理资源的代码工作的级别太低,无法确定正确的操作失败,因此异常会传播给调用者,调用者可以决定采取什么操作(例如重试,失败,记录等) ).你倾向于使用catch具有可支配资源的块的唯一地方是你要翻译异常(我认为,你的数据访问层正在做什么).
Rog*_*ger 14
using (var cmd = new SqlCommand("SELECT * FROM Customers"))
{
cmd.CommandTimeout = 60000;
...
}
Run Code Online (Sandbox Code Playgroud)
是语法糖
var cmd = new SqlCommand("SELECT * FROM Customers");
try
{
cmd.CommandTimeout = 60000;
...
}
finally
{
if (cmd != null)
cmd.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
因此,当人们告诉你"使用"是try/catch /的替代品时,他们暗示你应该使用长手形式但是添加你的catch块:
var cmd = new SqlCommand("SELECT * FROM Customers");
try
{
cmd.CommandTimeout = 60000;
...
}
catch (Exception ex)
{
...//your stuff here
}
finally
{
if (cmd != null)
cmd.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
Chu*_*way 12
将所有using语句包装到try/catch中.像其他人一样,使用的是清理实现IDisposable接口的类
try
{
using (var conn = new SqlConnection("..."))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "...";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// ...
}
}
}
}
}
catch(Exception ex)
{
//Handle, log, rethrow exception
}
Run Code Online (Sandbox Code Playgroud)
如果你想捕获异常,你可能应该回到使用try/catch/finally.只需将.Dispose()调用放在finally块中.
使用语句与异常无关.使用块只是确保在使用块中的对象上调用Dispose,当它退出该块时.IE:
using(SqlConnection conn = new SqlConnection(conStr))
{
//use conn
}//Dispose is called here on conn.
Run Code Online (Sandbox Code Playgroud)
如果打开连接会引发异常(或该块中的任何其他内容),它仍然会冒泡到顶部,就像任何其他无法处理的异常一样.
您仍然可以像以前一样捕获(或忽略)异常。重点是您不再需要担心数据库连接的处理。
即,如果您的应用程序要求您因其他原因(例如日志记录)捕获异常,则继续,但如果您只想释放数据库连接,则不再需要这样做:
using (SqlConnection conn = new SqlConnection(...))
{
// do your db work here
// whatever happens the connection will be safely disposed
}
Run Code Online (Sandbox Code Playgroud)
如果您想因其他原因捕获异常,您仍然可以这样做:
try
{
using (SqlConnection conn = new SqlConnection(...))
{
// do your db work here
// whatever happens the connection will be safely disposed
}
}
catch (Exception ex)
{
// do your stuff here (eg, logging)
// nb: the connection will already have been disposed at this point
}
finally
{
// if you need it
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35577 次 |
| 最近记录: |