Introduction to the implementation of the standard dispose mode in C #

Source: Internet
Author: User

C # The dispose method in the program. Once the object of this method is called, though there is no garbage collection, it can no longer be used. Therefore, you must carefully consider the details.

AD:

 

You need to clarify the resources in the C # Program (or. NET. Simply put, every type in C # represents a resource, and resources are divided into two categories:

Managed resources: Resources allocated and released by CLR management, that is, new objects in CLR;

Unmanaged resources: objects not managed by CLR, Windows kernel objects, such as files, database connections, sockets, and COM objects;

Without exception, if our types Use unmanaged resources, or we need to explicitly release managed resources, we need to let the type inheritance interface idisposable. This is equivalent to telling the caller that this type requires explicit resource release and you need to call my dispose method.

However, this is not so simple. A standard that inherits the type of the idisposable interface should be implemented as follows. This implementation is called the dispose mode:

  1. Public class sampleclass: idisposable
  2. {
  3. // Demonstrate creating an unmanaged Resource
  4. Private intptr nativeresource = marshal. allochglobal (100 );
  5. // Demonstrate creating a Managed Resource
  6. Private anotherresource managedresource = new anotherresource ();
  7. Private bool disposed = false;
  8. /// <Summary>
  9. /// Implement the dispose method in idisposable
  10. /// </Summary>
  11. Public void dispose ()
  12. {
  13. // The value must be true.
  14. Dispose (true );
  15. // Notify the garbage collection mechanism not to call the terminator (destructor)
  16. GC. suppressfinalize (this );
  17. }
  18. /// <Summary>
  19. /// It is not necessary to provide a close method only to better comply with the specifications of other languages (such as C ++ ).
  20. /// </Summary>
  21. Public void close ()
  22. {
  23. Dispose ();
  24. }
  25. /// <Summary>
  26. /// Required, in case that the programmer forgets to explicitly call the dispose method
  27. /// </Summary>
  28. ~ Sampleclass ()
  29. {
  30. // The value must be false.
  31. Dispose (false );
  32. }
  33. /// <Summary>
  34. /// Use protected virtual for non-seal class Modification
  35. /// Private for sealing class Modification
  36. /// </Summary>
  37. /// <Param name = "disposing"> </param>
  38. Protected virtual void dispose (bool disposing)
  39. {
  40. If (disposed)
  41. {
  42. Return;
  43. }
  44. If (disposing)
  45. {
  46. // Clear managed resources
  47. If (managedresource! = NULL)
  48. {
  49. Managedresource. Dispose ();
  50. Managedresource = NULL;
  51. }
  52. }
  53. // Clear unmanaged Resources
  54. If (nativeresource! = Intptr. Zero)
  55. {
  56. Marshal. freehglobal (nativeresource );
  57. Nativeresource = intptr. zero;
  58. }
  59. // Let the type know that it has been released
  60. Disposed = true;
  61. }
  62. Public void samplepublicmethod ()
  63. {
  64. If (disposed)
  65. {
  66. Throw new objectdisposedexception ("sampleclass", "sampleclass is disposed ");
  67. }
  68. // Omitted
  69. }}

In the dispose mode, almost every row has a special meaning.

In the standard dispose mode, we noticed ~ Method:

  1. /// <Summary>
  2. /// Required, in case that the programmer forgets to explicitly call the dispose method
  3. /// </Summary>
  4. ~ Sampleclass ()
  5. {
  6. // The value must be false.
  7. Dispose (false );
  8. }

This method is called the type Terminator. All the significance of providing the Terminator is that we cannot expect callers of the type to actively call the dispose method. Based on the features that the Terminator will be called by the garbage collector, the Terminator is used to remedy the resource release.

A type of dispose method should be allowed to be called multiple times without throwing an exception. For this reason, the type maintains a private Boolean variable disposed:

  1. Private bool disposed = false;

The following judgment statement is added to the actual code cleanup method:

  1. If (disposed)
  2. {
  3. Return;
  4. }
  5. // Omit the code for clearing part, and assign true to disposed at the end of the Method
  6. Disposed = true;

This means that if the type is cleared once, the cleanup will not proceed.

It should be noted that in the standard dispose mode, the dispose method that implements the idisposable interface is not actually cleaned up, it actually calls the following protected virtual method with a Boolean parameter:

  1. /// <Summary>
  2. /// Use protected virtual for non-seal class Modification
  3. /// Private for sealing class Modification
  4. /// </Summary>
  5. /// <Param name = "disposing"> </param>
  6. Protected virtual void dispose (bool disposing)
  7. {
  8. // Omitting the code
  9. }

This protected virtual method is provided to consider that this type will be inherited by other classes. If a subclass exists, the subclass may implement its own dispose mode. The protected virtual method is used to remind the subclass to pay attention to the cleanup of the parent class when implementing its own cleanup method. That is, the subclass must call the base. dispose method in its own release method.
Also, we should have noticed that the virtual method that actually writes the resource release code carries a Boolean parameter. This parameter is provided because hosting resources and unmanaged resources must be treated differently when resources are released.

In the no-parameter dispose method for explicitly releasing resources called by the caller, the call parameter is true:

  1. Public void dispose ()
  2. {
  3. // The value must be true.
  4. Dispose (true );
  5. // Others omitted
  6. }

This indicates that the Code must process both hosted and unmanaged resources at this time.

In the terminator for implicitly clearing resources called by the garbage collector, the call parameter is false:

  1. ~ Sampleclass ()
  2. {
  3. // The value must be false.
  4. Dispose (false );
  5. }

This indicates that you only need to process unmanaged resources during implicit cleanup.

Why do we treat managed and unmanaged resources differently. Before seriously explaining this issue, we need to first understand: Do managed resources need to be cleared manually? The types in C # can be divided into two categories. One Class inherits the idisposable interface, and the other class does not. The former is called a non-common type, while the latter is called a common type. Because a non-common type contains an unmanaged resource, it must inherit the idisposable interface. However, this type contains the unmanaged resource itself, which is a managed resource. So do managed resources need to be manually cleared? The answer to this question is: normal types in managed resources do not need to be cleared manually, rather than normal types. They need to be cleared manually (that is, the dispose method is called ).

The idea of designing the dispose mode is based on: If the caller explicitly calls the dispose method, the type should be released for all its own resources. If the caller forgets to call the dispose method, the type assumes that all of his managed resources (even the non-common types described in the previous section) are handed over to the Garbage Collector for recycling, instead of manual cleanup. After understanding this, we can understand why in the dispose method, the parameter passed in by the virtual method is true, and in the Terminator, the parameter passed in by the virtual method is true.

Note: we mentioned the need to release resources in a timely manner, but did not elaborate on whether to make reference equal to null in a timely manner. Some people think that null can help the garbage collection mechanism to discover and identify the object as garbage. Others think this is not helpful. Let's talk about this in the next article.

Link: http://www.cnblogs.com/luminji/archive/2011/03/29/1997812.html

[Edit recommendations]

  1. C # detailed description of the whole function instance application
  2. C # unit test
  3. C # analysis on the necessity of unit test
  4. C # analysis of unit test concepts and functions
  5. C # analysis of unit test operation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.