标签: try-catch-finally

try-catch-finally的用例同时包含catch和finally

我理解try-catch如何工作以及try-finally如何工作,但我发现自己在两个完全不同的场景中使用它们(通常):

  • try-finally(或using在C#和VB中)主要用于某些中型代码块,它使用一些需要正确处理的资源.
  • try-catch主要用于
    • 围绕一个单一的陈述,可以以一种非常具体的方式或失败
    • (作为一个包罗万象的)在应用程序的非常高级别,通常直接在一些用户界面操作下面.

根据我的经验,try-catch-finally最合适的情况,即我想要捕获某个特定异常的块与我使用某些可处理资源的块完全相同,这种情况极为罕见.然而,C#,VBJava的语言设计者似乎认为这是一个非常常见的场景; VB的设计师甚至考虑增加捕捉using.

我错过了什么吗?或者我是否因为限制性地使用try-catch而过于迂腐?


编辑:澄清:我的代码通常看起来像这样(为清晰起见,函数展开):

Try
    do something
    Aquire Resource (e.g. get DB connection)
    Try 
        do something
        Try
            do something that can fail
        Catch SomeException
            handle expected error
        do something else... 
    Finally 
        Close Resource (e.g. close DB connection)
    do something
Catch all
    handle unexpected errors
Run Code Online (Sandbox Code Playgroud)

这似乎比将两个捕获中的任何一个放在同一水平上更有意义,最后只是为了避免缩进.

c# java language-agnostic vb.net try-catch-finally

8
推荐指数
4
解决办法
6322
查看次数

finally子句java中的break语句

  public class FinallyTest {
    static int i=0;
    public static void main(String a[]){
        while(true){
            try{
                i=i+1;
                return;
            }finally{
                i=i+1;
                break;
            }
        }
        System.out.println(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码输出是'2'.我所期待的是什么都不应该打印出来.究竟什么'打破'在这做什么?请解释.谢谢

java break try-catch-finally

8
推荐指数
2
解决办法
8253
查看次数

为什么finally块中的代码不执行?

似乎finally块不执行,如果它不是主线程执行代码.在这种情况下是否有可能强制执行?

环境:VS 2010,.Net Framework 4.0.3

class Program
{
    static void Main(string[] args)
    {
        var h = new AutoResetEvent(false);

        ThreadPool.QueueUserWorkItem(
            obj => TestProc(h));

        h.WaitOne();
    }

    private static void TestProc(EventWaitHandle h)
    {
        try
        {
            Trace.WriteLine("Try");
            h.Set();
        }
        catch(Exception)
        {
            Trace.WriteLine("Catch");
        }
        finally
        {
            Thread.Sleep(2000);
            Trace.WriteLine("Finally");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

我在MSDN中找到了关于该案例的提及和解释:

ThreadAbortException类 http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx

当调用Abort方法来销毁线程时,公共语言运行库会抛出ThreadAbortException.ThreadAbortException是一个可以捕获的特殊异常,但它会在catch块的末尾自动再次引发.引发此异常,运行时会在结束线程之前执行所有finally块.因为线程可以在finally块中执行无限制计算或调用Thread.ResetAbort来取消中止,所以无法保证线程将永远结束.如果要等到中止的线程结束,可以调用Thread.Join方法.Join是一个阻塞调用,在线程实际停止执行之前不会返回.

注意:

当公共语言运行库(CLR)在托管可执行文件中的所有前台线程结束后停止后台线程时,它不使用Thread.Abort.因此,您无法使用ThreadAbortException来检测CLR何时终止后台线程.


前景和背景线程 http://msdn.microsoft.com/en-us/library/h339syd0.aspx

当运行时停止后台线程因为进程正在关闭时,线程中不会抛出异常.但是,当因为AppDomain.Unload方法卸载应用程序域而停止线程时,前台和后台线程中都会抛出ThreadAbortException.


那么为什么在应用程序结束时CLR不会使用AppDomain.Unload方法在主进程结束(kill)之前卸载应用程序域?因为http://msdn.microsoft.com/en-us/library/system.appdomain.unload.aspx:

当线程调用Unload时,目标域将标记为卸载.专用线程尝试卸载域,并且域中的所有线程都将中止.如果线程没有中止,例如因为它正在执行非托管代码,或者因为它正在执行finally块,那么在一段时间之后,在最初调用Unload的线程中抛出CannotUnloadAppDomainException.如果最终无法中止的线程结束,则不会卸载目标域.因此,在.NET Framework 2.0版域中不保证卸载,因为它可能无法终止执行线程.

结论:在某些情况下,我需要考虑我的代码是否会在后台或前台线程中执行?在应用程序主线程结束所有工作之前,我的代码是否可能无法完成?

.net c# multithreading try-catch-finally

8
推荐指数
1
解决办法
3063
查看次数

最后块是否真的需要清理代码(如关闭流)?

我很困惑为什么我需要将清理代码放在一个finally块中关闭流.

我已经读过finally块中的代码无论如何都会运行(是否存在异常); 并且在finally块运行之后,该方法的其余部分继续.

我的问题是:如果方法的其余部分必须继续,那么为什么我不在函数中的try/catch块之后放入清理代码?

java exception-handling try-catch-finally

8
推荐指数
2
解决办法
2184
查看次数

Powershell尝试Catch invoke-sqlcmd

当使用Invoke-Sqlcmd连接到SQL Server失败时,我在PowerShell中捕获错误时遇到问题.这是一些用于演示此问题的通用代码:

CLS
$server = "Localhost\fake"
try
{
    Invoke-Sqlcmd -Query "SELECT DB_NAME() as [Database]" -Server $server
}
catch
{
    Write-Host "Error connecting to server " $server
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Invoke-Sqlcmd:建立与SQL Server的连接时发生与网络相关或特定于实例的错误.服务器未找到或无法访问.验证实例名称是否正确,以及SQL Server是否配置为允许远程连接.(提供者:命名管道提供程序,错误:40 - 无法打开与SQL Server的连接)

我期待获得一行声明:"连接到服务器Localhost\fake时出错"

powershell try-catch try-catch-finally

8
推荐指数
1
解决办法
8445
查看次数

从try/catch块返回产量

正如Eric Lippert在本文中所描述的那样,yield return不允许在try/catch条款内.

有没有一种很好的方式我可以得到这样的东西,而不必IEnumerator手工编写我自己的东西:

public IEnumerable<Data> GetData()
{
    var transaction = Session.BeginTransaction());
    try 
    {
        IQuery q = CreateQuery(session);

        foreach (var result in q.Enumerable())
            yield return ProjectResult(result);  // <-- doesn't work

        session.Commit();
    }
    catch (Exception ex)
    {
        transaction.Rollback();
        throw;
    }
    finally
    {
        transaction.Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

c# transactions idisposable yield-return try-catch-finally

7
推荐指数
1
解决办法
4014
查看次数

单元测试最终在Java 6中阻塞

在查看我的代码覆盖率时,我注意到很多单元测试无法检查最终块,这些块试图关闭finally块中的打开InputStreams.

一个示例摘录是:

  try {
      f = new BufferedInputStream(new FileInputStream(source));
      f.read(buffer);
  } finally {
      if (f != null)
          try {
              f.close();
          } catch (IOException ignored) {
          }
      }
  }
Run Code Online (Sandbox Code Playgroud)

有没有适当的解决方案来使用JUnit4检查finally块内的所有内容?

我知道在保持最高生产力的同时,无法实现100%的代码覆盖率.然而,这些红线在报告中引人注目.

java exception-handling junit4 try-catch-finally java-6

7
推荐指数
2
解决办法
4302
查看次数

在try/catch块中最终"超出范围"

有没有办法访问在finally块中的try/catch块中创建的val?或者是最终块超出范围.

def myTryCatch: Either[Exception, String] = {
  try {
    val w = runOrFailWithException("Please work...")
    Right(w)
  } catch {
    case ex: Exception => {
      Left(ex)
    }
  }
  finally {
    // How do I get access to Left or Right in my finally block.
    // This does not work
    _ match {
      case Right(_) =>
      case Left(_) =>
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

scala try-catch-finally

7
推荐指数
1
解决办法
428
查看次数

最后添加return会隐藏异常

我有以下代码

public static void nocatch()
{
    try
    {
        throw new Exception();
    }
    finally
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

这给出了错误

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Unhandled exception type CustomException
Run Code Online (Sandbox Code Playgroud)

这是预期的,但returnfinally块中添加语句会使错误消失

public static void nocatch()
{
    try
    {
        throw new Exception();
    }
    finally
    {
        return; //makes the error go away! 
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下发生了什么事吗?为什么错误会消失?

注意:我编写此代码纯粹是为了实验目的!

java exception-handling exception try-catch try-catch-finally

7
推荐指数
1
解决办法
493
查看次数

什么是Java的"延迟"等价物

这只是Go代码的一个简短示例:

package main

import "fmt"

func main() {
    defer fmt.Println("world") //use of keyword 'defer'

    fmt.Println("hello")
}
Run Code Online (Sandbox Code Playgroud)

我在Java中找到了相当于'defer'的东西.

我可以使用而不是'推迟'

try {
    //do something
} finally {
    //code using defer
}
Run Code Online (Sandbox Code Playgroud)

没有使用try/catch/finally有没有其他选择?

java go try-catch-finally

7
推荐指数
1
解决办法
3813
查看次数