Both Finalize() and Dispose() methods are called to clean up unmanaged resources. Dispose method is user-driven unlike Finalize which is called when the Garbage collection happens hence it is unpredictable. Hence dipose is generally preferred over Finalize if you want to clean up unmanaged resources in your program thereby increasing the performance.

Following are some more points:

a. Finalize() method cannot be called by the user, it is called automatically by the Garbage collector when an object goes out of scope or inaccessible.
b. The finalize method is protected and hence it can be accessed through the containing class or its derived class.
c. As the class designer, it is always safe to provide the Finalize method. This is in case if the programmer fails to call the Dispose method on the unmanaged resoures, it would cause permanent leak of memory which can hamper performance. So to not to take the blame on yourself, providing Finalize method is always a good practise.

a. Dipose() method is called by the user to free up the unmanaged resources such as files, streams, database connections and handles.
b. When implementing dispose, after calling dispose, call GC.SupressFinalize method in order to prevent Finalize method from running to prevent performance issues.
c. The IDiposable interface contains the dipose method with no arguments and returns void.