【发布时间】:2012-03-06 16:18:57
【问题描述】:
在没有catch 块的情况下,是否适合使用try-finally 块?
【问题讨论】:
-
在 MSDN 上,请参阅 try-finally (C# Reference)。请注意,文章将
try和finally的组合使用称为“try-finally statement”。
标签: c# .net exception exception-handling
在没有catch 块的情况下,是否适合使用try-finally 块?
【问题讨论】:
try 和finally 的组合使用称为“try-finally statement”。
标签: c# .net exception exception-handling
1. 我们可以不使用 catch 使用 try 块,但我们应该使用 catch/finally, 其中任何一个。 2.我们不能只使用try块。
【讨论】:
在这种情况下,您可能希望使用 try finally:当您通常使用 using 语句,但由于您通过反射调用方法而不能使用时。
这行不通
using (objMsg = Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("omApp.MessagingBO")))
{
}
改为使用
object objMsg = null;
try
{
objMsg
= Activator.CreateInstance(TypeAssist.GetTypeFromTypeName("myAssembly.objBO"));
strResponse = (string)objMsg.GetType().InvokeMember("MyMethod", BindingFlags.Public
| BindingFlags.Instance | BindingFlags.InvokeMethod, null, objMsg,
new object[] { vxmlRequest.OuterXml });
}
finally
{
if (objMsg!=null)
((IDisposable)objMsg).Dispose();
}
【讨论】:
这是一个我一直(嗯..)使用的用例:
int? x; //note the nullable type here!
try
{
x = int.Parse(someString);
}
catch { } //don't care, let it just be null
【讨论】:
用代码很好的解释:
void MyMethod1()
{
try
{
MyMethod2();
MyMethod3();
}
catch(Exception e)
{
//do something with the exception
}
}
void MyMethod2()
{
try
{
//perform actions that need cleaning up
}
finally
{
//clean up
}
}
void MyMethod3()
{
//do something
}
如果 MyMethod2 或 MyMethod3 中的任何一个抛出异常,它将被 MyMethod1 捕获。但是,MyMethod2 中的代码需要运行清理代码,例如在将异常传递给 MyMethod1 之前关闭数据库连接。
【讨论】:
您可以使用它来确保在 try 内容之后或在异常时发生某些操作,但是当您不希望使用该异常时。
需要明确的是,这不会隐藏异常。 finally 块在异常向上传播到调用堆栈之前运行。
当您使用using 关键字时,您也会无意中使用它,因为这会编译成try-finally(不是精确转换,但为了论证,它已经足够接近了)。
try
{
TrySomeCodeThatMightException();
}
finally
{
CleanupEvenOnFailure();
}
不能保证在finally 中运行的代码可以运行,但是不能保证的情况是相当先进的——我什至不记得了。我只记得,如果你在这种情况下,很有可能不运行finally 不是你最大的问题:-) 所以基本上不要出汗。
来自 Tobias 的更新:如果进程被杀死,finally 将不会运行。
来自 Paddy 的更新: Conditions when finally does not execute in a .net try..finally block
您可能会看到的最普遍的例子是即使代码失败也会处理数据库连接或外部资源:
using (var conn = new SqlConnection("")) // Ignore the fact we likely use ORM ;-)
{
// Do stuff.
}
编译成 something 比如:
SqlConnection conn;
try
{
conn = new SqlConnection("");
// Do stuff.
}
finally
{
if (conn != null)
conn.Dispose();
}
【讨论】:
using 等价于 try-finally。当您想在finally 内部进行一些清理并且不关心异常时,您只会使用try-finally。
最佳方法将是
try
{
using(resource)
{
//Do something here
}
}catch(Exception)
{
//Handle Error
}
这样做即使using 调用的清理失败,您的代码也不会失败。
finally 在某些情况下不会被执行。
StackOverflowException或ExecutingEngineException。希望这能解答您的疑问。
【讨论】:
我对 C# 一无所知,但似乎你可以用 try-finally 做的任何事情,你都可以更优雅地用 using statement 做。 C++ 甚至没有finally as a result of its RAII。
【讨论】:
try 中增加一个计数器,然后在finally 中减少它,你不能在using 语句中这样做。
Try-[Catch]-Finally 可以处理所有这些,而无需创建这样的对象。
using,但你不能像你一样做出一揽子声明。同样,这是通过解决方案来定义问题,对我来说这是倒退的。
例如,如果您有一个在 try 块中创建和使用的非托管资源,则可以使用 finally 块来确保释放该资源。尽管 try 块中发生了什么(例如异常),finally 块将始终执行。
例如lock(x) 语句真的是:
System.Threading.Monitor.Enter(x);
try { ... }
finally
{
System.Threading.Monitor.Exit(x);
}
总是会调用 finally 块以确保释放排他锁。
【讨论】:
这取决于您的应用程序的架构以及您在块中执行的操作。
【讨论】:
try/finally:当您不想处理任何异常但想确保某些操作发生时,无论调用代码是否抛出异常。
【讨论】:
你需要一个 finally 块,当无论哪个(如果有)异常被捕获,或者即使没有被捕获,你仍然希望在块退出之前执行一些代码。例如,您可能想要关闭一个打开的文件。
【讨论】: