关于抛出和异常冒泡

时间:2010-11-01 00:13:52

标签: c# exception-handling

我的问题是关于抛出和异常冒泡。我正在四处搜索文件锁定和C#,我试着弄乱某人的代码,这让我对我对抛出和异常冒泡的理解有所了解。

Here是该主题的链接。

public class FileManager
{
private string _fileName;
private int _numberOfTries;

private int _timeIntervalBetweenTries;

private FileStream GetStream(FileAccess fileAccess)
{
    var tries = 0;
    while (true)
    {
        try
        {
            return File.Open(_fileName, FileMode.Open, fileAccess, Fileshare.None); 
        }
        catch (IOException e)
        {
            if (!IsFileLocked(e))
                throw;
            if (++tries > _numberOfTries)
                throw new MyCustomException("The file is locked too long: " + e.Message, e);
            Thread.Sleep(_timeIntervalBetweenTries);
        }
    }
}

private static bool IsFileLocked(IOException exception)
{
    int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
    return errorCode == 32 || errorCode == 33;
}

// other code

}

在上面的代码中,如果 IsFileLocked 返回false,则抛出重新抛出IOException。据我所知,我认为现在IOException会冒出堆栈跟踪。至少对我来说,这意味着当发生抛出时,它应该再次被catch(IOException e)捕获(显然在GetStream方法中)​​。毕竟,堆栈跟踪类似于:

GetStream(处理IOExceptions) IsFileLocked 扔 异常将在GetStream

中处理

然而,当我运行它时,它似乎没有烦恼,而是停止我的应用程序。我在这里错过了什么吗?

旁注:就这样,我得到了throw和throw ex之间的区别,如果使用了throw ex,那么异常会显示来自GetStream然后冒泡到没有哪里对吗?我知道这里有同样的问题,我只想在这个例子中重申这是真的。

由于

2 个答案:

答案 0 :(得分:9)

来自catch块的异常抛出(或重新抛出)不会由同一个catch块处理,而是由链上的下一个异常处理程序处理。如果没有其他处理程序(并且没有适当的全局异常处理程序来正常处理异常),则应用程序将终止。

关于您的附注,throw会在异常上保留调用堆栈,但throw ex重新引发的异常似乎来自GetStream()

答案 1 :(得分:1)

throw中的普通catch不会再次被抓到。只会抓住try块引发的异常。您的异常将继续调用堆栈。

你是对的,throwthrow ex的堆栈跟踪可能不同,但堆栈跟踪不是决定捕获异常的位置,抛出站点是。