我有一些看起来像这样的代码:
foreach(var obj in collection)
{
try
{
// WriteToFile returns the name of the written file
string filename = WriteToFile(obj);
SendFileToExternalAPI(filename);
}
catch ( ArbitraryType1Exception e )
{
LogError(e);
continue;
}
...
catch ( ArbitaryTypeNException e )
{
LogError(e);
continue;
}
finally
{
try
{
File.Delete(filename);
}
catch (Exception e)
{
LogError(e);
}
}
}
目标是尝试为集合中的每个对象写出一个临时文件,尝试将该文件加载到需要文件名的外部API中,然后在完成后清理临时文件。如果在将文件写入磁盘或将其加载到外部API时发生错误,我只想记录错误并转到下一个对象;我无法询问用户该做什么。
当你在catch处理程序中有continue语句时,我有点不确定finally块的时序是如何工作的。无论是否在try块中抛出异常,此代码是否会(尝试)删除正确的文件?或者,在finally块运行之前,catch语句中的continue是否生效?
答案 0 :(得分:13)
将其视为具有catch表达式可选的try / finally块。代码中的两个continue语句都会将执行堆栈弹出catch,这会在允许循环继续之前将执行放在finally块中。任何时候有一个try / finally块,最后总会被执行。
答案 1 :(得分:8)
无论是否抛出异常,都将执行finally块。因此,您的finally块将始终执行。
答案 2 :(得分:6)
finally
将作为try
完成之前的最后一步执行。因此它将在合适的时间发生。为了便于概念化,请考虑如果所有continue
语句都被return
替换会发生什么 - finally
仍会执行。
答案 3 :(得分:6)
8.9.2继续声明
...
continue语句不能退出finally块(第8.10节)。当一个 continue语句发生在finally块中,目标是 continue语句必须在同一个finally块中;否则一个 发生编译时错误。
continue语句执行如下:
·如果continue语句退出一个或多个try块 关联最后块,控制最初转移到 最后阻止了最里面的try语句。什么时候控制 到达finally块的终点,控制转移到 下一个封闭的try语句的finally块。这个过程是 重复,直到所有介入的try语句的finally块 已被执行。
...