As jo0ls said, it is probably
technically better to release your worksheet object when you are done with it and still have a reference to it, before moving on to the next object.
That said, as a practical matter, I find this style of coding to be way too cumbersome, and you are likely to forget to do it somewhere anyway at some point -- maybe lots of points!
In my own coding, I do not bother releasing each and every object as I use them and I never get a hang. Within your cleanup/shutdown section, the key is, to call GC.Collect() and then GC.WaitForPendingFinalizers()
before releasing the objects to which you do have a reference, and then release your remaining objects via Marshal.FinalReleaseComObject() in order from least important object to the most important (for example, Range objects first, then Worksheets, then Workbooks, and then finally your Application object).
Take a look at the two posts that jo0ls listed, which go into how to do this in detail. I think that the
StackOverflow Article on Cleaning up COM Objects is probably the most on point here, but also read the
Automating Office Programs with VB.NET article that jo0ls mentioned.
If you follow this approach, your code can be a lot cleaner and you shoudn't have any hangs.
