使用'try-finally'块而不使用'catch'块

时间:2012-02-15 10:14:21

标签: c# .net exception exception-handling

是否存在使用try-finally块而没有catch块的情况?

11 个答案:

答案 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无法执行时会出现一些情况。

  • 如果有StackOverflowExceptionExecutingEngineException
  • 进程被外部来源杀死。

希望这能回答你的疑问。

答案 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之前关闭数据库连接。

http://forums.asp.net/t/1092267.aspx?Try+without+Catch+but+with+finally+doesn+t+throw+error+Why+no+syntax+error+

答案 4 :(得分:1)

你需要一个finally块,当不管捕获哪个(如果有的话)异常时,或者即使没有被捕获,你仍然希望在块退出之前执行一些代码。例如,您可能想要关闭一个打开的文件。

另见try-finally

答案 5 :(得分:1)

try / finally:当你不想处理任何异常但希望确保一些动作发生时,无论被调用的代码抛出异常。

答案 6 :(得分:1)

看看以下链接: https://softwareengineering.stackexchange.com/questions/131397/why-use-try-finally-without-a-catch-clause

这取决于应用程序的体系结构以及您在块中执行的操作。

答案 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。