The Problem with finalize is that the garbage collection has to make 2 rounds in order to remove the objects which have finalize methods.
The figure below will make things clear regarding the two rounds of garbage collection rounds performed for the objects having finalized methods.
In this scenario there are 3 objects Object1, Object2 and Object3. The Object2 has the finalize method overridden and remaining objects do not have the finalize method overridden.
Later when garbage collector runs for the first time it searches for the objects whose memory has to free. He can see 3 objects but it only cleans the memory for Object1 and Object3.The Object2 it pushes to the finalization queue.
Now garbage collector runs for the second time. He views that there are no objects to be released and then checks for the finalization queue and at this moment it clears object2 from the memory.
So if you notice that object2 was released from memory in the second round and not first. That's why the best method is not to write clean up Non.NET resources in Finalize method rather use the DISPOSE.