我的问题是关于抛出和异常冒泡。我正在四处搜索文件锁定和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然后冒泡到没有哪里对吗?我知道这里有同样的问题,我只想在这个例子中重申这是真的。
由于
答案 0 :(得分:9)
来自catch
块的异常抛出(或重新抛出)不会由同一个catch
块处理,而是由链上的下一个异常处理程序处理。如果没有其他处理程序(并且没有适当的全局异常处理程序来正常处理异常),则应用程序将终止。
关于您的附注,throw
会在异常上保留调用堆栈,但throw ex
重新引发的异常似乎来自GetStream()
。
答案 1 :(得分:1)
throw
中的普通catch
不会再次被抓到。只会抓住try
块引发的异常。您的异常将继续调用堆栈。
你是对的,throw
和throw ex
的堆栈跟踪可能不同,但堆栈跟踪不是决定捕获异常的位置,抛出站点是。