是否存在使用try-finally
块而没有catch
块的情况?
答案 0 :(得分:95)
您可以使用它来确保在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.
}
编译成某些内容,如:
SqlConnection conn;
try
{
conn = new SqlConnection("");
// Do stuff.
}
finally
{
if (conn != null)
conn.Dispose();
}
答案 1 :(得分:5)
using
相当于try-finally
。如果您想在try-finally
内进行一些清理并且不关心异常,则只能使用finally
。
最佳方法将是
try
{
using(resource)
{
//Do something here
}
}catch(Exception)
{
//Handle Error
}
这样做即使using
调用的清理失败,您的代码也不会失败。
finally
无法执行时会出现一些情况。
StackOverflowException
或ExecutingEngineException
。希望这能回答你的疑问。
答案 2 :(得分:3)
如果您具有在try块中创建和使用的非托管资源,则可以使用finally块来确保释放该资源。尽管try块中发生了什么(例如异常),但始终会执行finally块。
E.g。 lock(x)语句确实是:
System.Threading.Monitor.Enter(x);
try { ... }
finally
{
System.Threading.Monitor.Exit(x);
}
将始终调用finally块以确保释放独占锁。
答案 3 :(得分:2)
使用代码进行良好解释:
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之前关闭数据库连接。
答案 4 :(得分:1)
你需要一个finally块,当不管捕获哪个(如果有的话)异常时,或者即使没有被捕获,你仍然希望在块退出之前执行一些代码。例如,您可能想要关闭一个打开的文件。
答案 5 :(得分:1)
try / finally:当你不想处理任何异常但希望确保一些动作发生时,无论被调用的代码抛出异常。
答案 6 :(得分:1)
这取决于应用程序的体系结构以及您在块中执行的操作。
答案 7 :(得分:1)
在这种情况下,您可能希望最终使用try:当您通常使用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();
}
答案 8 :(得分:0)
我对C#一无所知,但似乎你可以通过try-finally做任何事情,你可以更优雅地使用using statement。 C ++甚至没有最终为a result of its RAII。
答案 9 :(得分:0)
这是一个我总是(嗯......)使用的用例:
int? x; //note the nullable type here!
try
{
x = int.Parse(someString);
}
catch { } //don't care, let it just be null
答案 10 :(得分:0)
1.我们可以使用没有catch的try块但我们应该使用catch / finally, 其中任何一个。 2.我们不能只使用try block。