I have been talking about it for a long time. msdn also has a very detailed description, but it does not seem very systematic. I have also done some analysis, but I did not forget to summarize it. This time, I will sort out some information collected on msdn and the Internet for the sake of time.
The following describes how to use the two functions in msdn.
Msdn suggestions
1 // design pattern for a base class. 2 public class base: idisposable 3 {4 // system exception 5 private bool _ isdisposed = false when resources are repeatedly released; 6 7 // destructor, the compiler automatically generates finalize () the function is automatically called by GC to ensure that resources are recycled. 8 // It is recommended that you do not declare an empty destructor, resulting in performance problems 9 // if you do not reference an unmanaged resource, you do not need to display the Declaration destructor, which may cause performance problems, the system automatically generates the default destructor 10 ~ Base () 11 {12 // you only need to release the unmanaged code here, because this object resource may not need to release 13 dispose (false) during GC calls ); 14} 15 16 // manually called externally or automatically called in using, and released both managed and unmanaged resources 17 Public void dispose () 18 {19 dispose (true); 20 GC. suppressfinalize (this); // tell GC that you do not need to call 21} 22 23 protected virtual void dispose (bool disposing) 24 {25 if (! _ Isdisposed) 26 {27 if (disposing) 28 {29 // release managed resources 30} 31 // release unmanaged resources 32 // release large objects 33 34 this. _ isdisposed = true; 35} 36 37} 38 39}
The following is the result of reflection from the above code using the reflector tool. We can see that the Destructor is directly translated into the finalize () function, because the finalize function cannot be rewritten, therefore, you can only use the destructor to implement the Finalize method.
Reflector reflection results
1 public class Base : IDisposable 2 { 3 // Fields 4 private bool _isDisposed; 5 6 // Methods 7 public Base(); 8 public void Dispose(); 9 protected virtual void Dispose(bool disposing);10 protected override void Finalize(); 11 }
In fact, there are two functions used to release resources in the. NET object: dispose and finalize. Finalize is used to release unmanaged resources, while dispose is used to release all resources, including hosted and unmanaged resources.
In this mode, the void dispose (bool disposing) function uses a disposing parameter to determine whether the current call is called by dispose. If it is called by dispose (), you need to release both hosted and unmanaged resources. If it is ~ Base () (that is, the finalize () of C #) is called, you only need to release the unmanaged resources.
This is because the dispose () function is explicitly called by other code and requires resource release, while finalize is called by GC. When GC is called, other Managed Objects referenced by the base may not need to be destroyed, and GC calls the base even if it is to be destroyed. Therefore, you only need to release unmanaged resources in finalize. On the other hand, because managed and unmanaged resources have been released in dispose (), it is unnecessary to call finalize again when the object is recycled by GC. Therefore, in dispose (). suppressfinalize (this) prevents repeated calls to finalize.
However, even if you call finalize and dispose repeatedly, the resource is released only once because of the existence of Variable _ isdisposed. Excessive calls are ignored. Therefore, the above mode ensures that:
1. Finalize only releases unmanaged resources;
2. Dispose releases managed and unmanaged resources;
3. It is no problem to repeatedly call finalize and dispose;
4. Finalize and dispose share the same resource release policy, so there is no conflict between them.
Microsoft guidelines for dispose and finalize
Finalize
The following rules summarize finalizeUsage rules:
1. The Destructor cannot be defined in the structure. Only destructor can be used for classes.
2. A class can have only one destructor.
3. The Destructor cannot be inherited or overloaded.
4. You cannot call the destructor. They are automatically called.
5. The Destructor neither have modifiers nor parameters.
- Implement finalize only on the object to be terminated. Performance overhead related to the Finalize method exists.
- If you need the Finalize method, you should consider implementing idisposable so that class users can avoid overhead caused by calling the Finalize method.
- Do not increase the visibility of the Finalize method. The visibility of this method should be protected, not public.
- The Finalize method of the object should release all external resources owned by the object. In addition, the Finalize method should only release resources controlled by this object. The Finalize method should not reference any other objects.
- Do not directly call the Finalize method for objects that are not the object's base class. In C # programming language, this is not a valid operation.
- The Finalize method of the base class should be called in the Finalize method of the object.
Note:
The Finalize method of the base class is automatically called through the C # And C ++ destructor syntax.
Release
The following rules summarize the disposeUsage rules:
- Release the design scheme by specifying the type of resources to be released in encapsulation. You can call the public dispose method to release external resources.
- Release the design scheme on the base types that generally contain derived types that control resources, even if the base type is not required. If the base type has the close method, this usually indicates the implementation of dispose. In this case, do not implement the Finalize method on the base type. Finalize should be implemented in any derivative type that introduces the resources to be cleared.
- Use the dispose method of the type to release all resources of the type.
- After dispose is called for an instance, the Finalize method should be disabled by calling GC. suppressfinalize. An exception to this rule is when you must use finalize to complete the work that dispose has not completed, but this is rare.
- If the base class implements idisposable, call the dispose method of the base class.
- Do not assume that dispose will be called. If dispose is not called, use the Finalize method to release the unmanaged resources of the type.
- When the resource has been released, an objectdisposedexception is triggered from the instance method (not dispose) On this type. This rule is not applicable to the dispose method. This method should be called multiple times without exception.
- Transmits the call to dispose through the hierarchical structure of the Base type. The dispose method should release all resources controlled by this object and any object owned by this object. For example, you can create an object similar to textreader to control stream and encoding, both of which are created by textreader without the user's knowledge. In addition, both stream and encoding can obtain external resources. When the dispose method is called for textreader, textreader should then call dispose for stream and encoding to release their external resources.
- We recommend that you disable the use of an object after calling the dispose method of an object. It is difficult to recreate released objects.
- The dispose method can be called multiple times without exception. This method should do nothing after the first call.
Below is a summary of csdn experts
1. The Finalize method (C # Is a destructor, hereinafter referred to as a destructor) is used to release unmanaged resources, and managed resources are automatically reclaimed by GC. Therefore, we can also distinguish between hosted and unmanaged resources. All resources that will be automatically recycled by GC are managed resources, but those that cannot be automatically recycled by GC are unmanaged resources. There are few cases where we directly use unmanaged resources in our classes, so we basically don't need to write destructor.
2. Most of the unmanaged resources will have many negative effects on the system. For example, if the database connection is not released, the available database connections in the connection pool may be exhausted. If the file is not closed, other processes cannot read and write the file.
Implementation Model:
1. Because most of the unmanaged resources require manual release, we should publish a method specifically to release the unmanaged resources. The dispose method that implements the idispose interface is the best model. Because C # supports using statements quickly, you can automatically call the dispose method when leaving the statement block.
2. Although you can manually release unmanaged resources, we still need to release the unmanaged Resources in the destructor. This is a secure application. Otherwise, if the programmer forgets to manually release the unmanaged resources due to negligence, it will have disastrous consequences. Therefore, releasing unmanaged resources in destructor is a remedy, at least for most classes.
3. Because the calling of the Destructor will reduce the efficiency of GC in object collection, if you have completed the tasks of the Destructor (such as releasing unmanaged resources ), the suppressfinalize method should be used to tell GC that the destructor of an object does not need to be executed.
4. Only unmanaged resources can be released in the destructor, and no operations can be performed on any managed objects/resources. Because you cannot predict the running time of the destructor, when the Destructor is executed, the managed resources you operate on may have been released. This will cause serious consequences.
5. (This is a rule) If a class has a member that implements the idispose interface type and is created (note that it is created rather than received and must be created by the class itself) its instance object, the class should also implement the idispose interface, and call the dispose method of all the Members that implement the idispose interface in the dispose method.
Only in this way can we ensure that the dispose method of all objects that implement the idispose interface can be called, and that any resources that need to be released can be manually released.