I am pretty new to programming in VB.Net, but I have been programming in other languages for a couple of decades now, including VB5/6 and C++.

When I am using a Try - Catch block to handle exceptions, what is the point of a Finally section? Wouldn't it be just the same as putting code after the End Try? So why use a Finally section because it looks like it just gets executed after everything else in the block, which is the same behaviour as code after the Try - Catch block.

Dani AI

Generated

Short answer: Finally is where you put code that must run when control leaves the Try block no matter how it leaves — normal completion, a Return/Exit, an exception, or a rethrow. As pointed out, it keeps cleanup logic visually and logically tied to the Try/Catch, and as noted it will run before any return actually hands control back to the caller.

Prefer patterns that reduce manual cleanup. For IDisposable resources use VB's Using (the compiler emits a try/finally that calls Dispose for you):

Using conn As New SqlConnection(connString)
    conn.Open()
    ' work with connection
End Using

A few practical tips that expand on the thread:

  • Finally runs even if you rethrow an exception; it executes before the exception continues up the stack. Use Throw (not Throw ex) in a Catch to preserve the original stack trace.
  • Avoid doing heavy work or throwing more exceptions from Finally. If Finally throws, that new exception will replace the original and hide the root cause. Log carefully or catch inside Finally if cleanup might fail.
  • Finally is not a guaranteed "always" in the sense of process-level termination: if the process is killed abruptly (Environment.FailFast, Process.Kill, power loss, or some catastrophic runtime failures) Finally will not run.

Use Finally for deterministic cleanup and restoring invariants (release locks, rollback or mark a transaction as failed if not committed, close unmanaged handles). Use Using for IDisposable objects where possible. This keeps resources safe, stack traces meaningful, and the code easier to maintain — exactly the maintenance benefit described and the behavior warned about with early returns.

Recommended Answers

All 4 Replies

Because the code in the Finally is always executed you might wonder what's the point. The point is that the code in the Finally block is logically associated with the code in the Try and Catch blocks. If you saw

Try
    'some statements
Catch ex As Exception
    'some more statements
End Try

'some other statements

You might (at some point) either be tempted to insert more code after the End Try, or move the code after the End Try somewhere else. However, if you saw

Try
    'some statements
Catch ex As Exception
    'some more statements
Finally
    'some other statements
End Try

you would know immediately that "some other statements" is associated with "some statements" and "some more statements". Typically, the Finally block contains cleanup code. For example, if, in the Try block, you opened one or more files, you'd want to close those files whether or not an exception occurs. Rather than duplicate this code in the Try and Catch blocks, you place it in the Finally block.

So if I understand this now, which could still be in doubt, as an example, I create an object in Try. Catch handles the errors and Finally is here I Dispose of the object, if it is not going to used afterward.

Try
    stmTesting = New IO.StreamReader(strFilename)

Catch ex AS IOException
    REM Could not open the file for some reason.
    ' Do whatever to try to recover.
Finally
    REM I am just checking if the file can be openned at this point.
    REM I don't need to read it now.
    If Not (stmTesting Is Nothing) Then
        stmTesting.Close
        stmTesting = Nothing
    End If
End Try

Is that the idea?

Nutster, you may find this article helpful: Click Here

The code placed under the "Finally" section can be viewed like an in-place method definition that will always be called before leaving the "Try-End Try" block.

Let's say in your IOException example, that you can not recover from the file error and need to return control to the calling procedure via an "Exit Sub", "Exit Function", or "Return" statement. The "Finally" code will execute before the return. You could accomplish the same thing without using the "Finally" section, but it keeps the logic all together and easier to maintain.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.