I understand that it is used to deallocate unmanaged resources, however, I am confused as to when Dispose is actually called. I know it is called at the end of
No it does not get called when the object is garbage collected. If you want that behavior you can use the destructor (finalizer) and the call Dispose() from there.
As you say it is automatically called and the end of a using block.