1. The difference between the two methods Close and Dispose
After calling the object's Close method, this object may be reused; for the Dispose method, the resources occupied by this object need to be marked as useless, that is, the object is to be destroyed and cannot be used anymore. For example, the SqlConnection class in common .Net class library, after calling the Close method, you can reopen a database connection through Open. When you completely use this object, you can call the Dispose method to mark this object useless and wait for GC to recycle.
The difference between the two and three is shown in the figure
Destructor | Dispose method | Close method | |
significance | Destroy the object | Destroy the object | Close the object resource |
Call method | Cannot be called by display, in GC recycling is called | Need to display the call or pass the using statement | Need to display the call |
Call time | uncertain | OK, in the display call or leave the using program block | OK, when displaying the call |
3. Description of destructor and Dispose
Dispose needs to implement the IDisposable interface.
Dispose is called by the developer code, while the destructor is called automatically by the GC.
The Dispose method should free up all managed and unmanaged resources. The destructor should only release unmanaged resources. Because the destructor is judged and called by GC, when GC determines that an object is no longer needed, its destructor method is called, and the object may also contain other useful managed resources.
The code "(this);" is added at the end of the Dispose method, which tells GC that it does not need to call the destructor method of the object. Otherwise, GC will still call its destructor method after judging that the object is no longer useful. Although the program will not make any errors, it will affect system performance.
The resource released by the destructor and Dispose should be the same, so that the resource will be released in Finalize even if the class consumer does not call Dispose.
Finalize should not be public.
Releasing resources frequently through system GC will reduce system performance, so it is recommended to call the Dispose method.
When a Dispose method exists, it should be called because Finalize is usually slow to release resources.
4. Description of Close function
Close This method has different meanings in different classes, and there is no regulation that requires Close to have a special meaning, that is, Close does not necessarily need to release resources, and you can also let the Close method represent "close". However, since Close means "related", Close is usually used to release resources, which is also allowed. For example, in file operations, using Close to release objects seems to have a more accurate meaning than Dispose. Therefore, when designing a class, you can set Close to public, Dispose to protected, and then call Dispose by Close. In other words, what does Close mean? Whether it will release resources is entirely determined by the class designer. It is said online that "Close calls Dispose" is very one-sided. In SqlConnection, Close only means closing the database connection and not releasing the object resource of the SqlConnection. According to experience, when Close and Dispose exist at the same time (both public), Close does not mean releasing resources, because usually, class designers should not use two public methods to free the same resource.
5. Destructor and Dispose method examples
{
//We mentioned earlier that the destructor is actually rewritten the virtual method Finalize. By default, a class does not have a destructor, that is, the Finalize method will not be called when the object is garbage collected.
~BaseResource()
{
// In order to maintain the readability and maintainability of the code, never write code to release unmanaged resources here.
// It must be called in Dispose(false) mode, and false tells the Dispose(bool disposing) function to be called from the garbage collector when calling Finalize.
Dispose(false);
}
// Cannot be called directly by the client
// If disposing is true, then this method is called directly by the customer, and both managed and unmanaged resources can be released.
// If disposing is false, then the function is called from the garbage collector when calling Finalize. Other managed objects should not be referenced at this time, so it can only release unmanaged resources.
protected virtual void Dispose(bool disposing)
{
// Then this method is called directly by the customer, and both managed and unmanaged resources can be released.
if (disposing)
{
// Release managed resources
();
}
//Release unmanaged resources
DoUnManagedObjectDispose();
// Then this method is called directly by the customer, telling the garbage collector to clear itself from the Finalization queue, thereby preventing the garbage collector from calling the Finalize method.
if (disposing)
(this);
}
//Can be called directly by the client
public void Dispose()
{
//It must be called in Dispose(true) mode, and tells the Dispose(bool disposing) function to be called directly by the client with true.
Dispose(true);
}
}
The purpose of the above example:
1/ If the customer does not call Dispose() and fails to release managed and unmanaged resources in time, then during garbage collection, there is still a chance to execute Finalize() to release unmanaged resources, but it causes idle waste of unmanaged resources that are not released in time.
2/ If the customer calls Dispose(), the managed and unmanaged resources can be released in time. Then when the object is garbage collected, Finalize() will not be executed again, which improves the efficiency of the unmanaged resources and improves the system performance.
at last:
If you use unmanaged resources in your class, you should consider providing Close methods, and Open methods. And call the Close method first in your Dispose method.
When using already existing classes, such as SqlConnection. If you do not use this connection for the time being, you can consider using the Close() method. If you don't use it, consider calling the Dispose() method.