我有一些代码看起来像这样:
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 语句时,最终块的时间是如何工作的。无论 try 块中是否引发异常,此代码是否会(尝试)删除正确的文件?还是 catch 语句中的继续在最终块运行之前生效?
将其视为带有可选捕获表达式的 try/finally 块。 代码中的两个 continue 语句都会将执行堆栈从 catch 中弹出,这会在允许循环继续之前将执行放在 finally 块中。 任何时候有 try/finally 块,finally 将始终被执行。
无论是否抛出异常,您的 finally 块都将被执行。因此,您的最终块将始终执行。
finally
将作为try
完成之前的最后一步执行。因此,它将在正确的时间发生。为了更容易概念化,请考虑如果所有continue
语句都替换为 return
会发生什么 - finally
仍将执行。
来自 C# 语言规范:
8.9.2 继续语句
。
继续语句不能退出 finally 块 (§8.10)。当一个继续语句发生在 finally 块中,目标是继续语句必须位于同一 finally 块中;否则发生编译时错误。
继续语句按如下方式执行:
· 如果 continue 语句退出一个或多个 try 块,则关联的最终块,控制权最初转移到最后阻止最里面的尝试语句。何时以及是否控制到达最终块的终点,控制权转移到下一个封闭的 try 语句的最后一个块。这个过程是重复直到所有干预 try 语句的最终块已被执行。
。