SHORT ANSWER
Calling GC.Collect() will complete the garbage collection and wait for it to complete, but it will NOT wait for the pending finalizers to complete.
LONG RESPONSE
You are partially correct in your assumptions, because the GC runs in one or more background threads to run finalizers. (But see the footnote at the end of this answer.)
However, you can wait for the GC to complete by calling GC.WaitForFullGCComplete() and GC.WaitForPendingFinalizers() after calling GC.Collect() :
GC.Collect(); GC.WaitForPendingFinalizers(); GC.WaitForFullGCComplete();
However, keep in mind that the thread on which the finalizers are running is not specified, so there is no guarantee that this method will complete.
Note that you should not use the GC in this way; I assume that you have a special case that you need to address, or you are doing this for research purposes.
The only acceptable case that I saw for this is when the application closes and you want to (try) to make sure that all finalizers are running, because, for example, they will clear the log files, etc.
As noted above, this still does not guarantee that all finalizers are running; it's just the best you can do.
In response to your point (5):
The documentation for GC.Collect () states:
It makes you immediately collect garbage of all generations.
So it will force the GC.
The documentation also states:
Use this method to try to recover all inaccessible memory.
The use of the word โtryโ simply means that even if a full GC is running, not all inaccessible memory will be fixed. There are several reasons that may arise, for example, a finalizer may block.
Footnote
.Net 4.5 allows you to specify whether GC.Collect() will be blocked or not .
In fact, the documentation for GC.Collect() states that it collects garbage from all generations, which seems to contradict my statements above. However, there seems to be some confusion as to whether this is true.
See for example this thread .
The answer is: GC.Collect() will by default wait for all generations to be GCed, but will not wait for pending finalizers, which are always executed in a separate thread.
Therefore, if you do not need to wait for finalizers, you only need to call GC.Collect() , and you do not need to wait for anything else.