Finally гарантирует выполнение кода, независимо от того, была ошибка или нет.
А что будет, если код, обрабатывающий исключение, сам вбросит исключение?
try
{
throw new ArgumentException();
}
catch(Exception)
{
// any new exception thrown here
}
CodeCleanup();
В данном случае выполнение логики прервется, соответственно, метод CodeCleanup не будет выполнен.
Подобное может случиться, например при вызовах методов, которые выполняют определенные сетевые операции, которые отваливаются по Timeout-у. В таком случае обычно делают N-ое кол-во повторных вызовов того же метода, чтобы исключить проблемы, связанные с настабильностью сети.
Finally решает эту проблему.