Source Address: Github.com/hiramtan/hiframework_unity/blob/master/unity/assets/hiframework/extensions/objectbase.cs
Describe the managed and unmanaged resources before you say the resource is recycled.
1. Managed resources are maintained by the CLR and are automatically garbage collected, such as arrays.
2. Unmanaged resources are not automatically garbage collected and need to be released manually, such as handles. But many of the unmanaged resources in C # are encapsulated. NET class, an internal method frees an unmanaged resource while the object is disposed.
For example, a socket connection, encapsulated as a socket class in. NET, decompile the Socket class library, and see that a handle was created when the connection object was created
But when the upper user uses the socket and does not find the logic to release the handle, who does the release logic do? We continue to decompile the Close method of the socket.
The IDisposable interface to be addressed in this article will eventually be called. In disposable, the internal socket logic frees managed resources such as cache and unmanaged resources, such as connection handles.
Now that the managed and unmanaged resources are clear, the following formally describes the use of the IDisposable interface.
objects created in C #, arrays, lists ... There is no need to consider the issue of resource deallocation because it is automatically reclaimed by the CLR's garbage collection mechanism. For example, there is a objectbase class that creates this object and then empties it, which is automatically reclaimed after a period of time:
objectbase ob = new Objectbase ();
OB = null;
How to be sure that this object is actually recycled, we introduce its destructor:
public class Objectbase
{
~objectbase ()
{
Console.WriteLine (" Dispose Finish ");
}
}
There is a problem: The created object is randomly released when the automatic recovery mechanism is random, there is no way to proactively reclaim these resources, such as objects occupy large memory, want to actively release immediately without waiting for active recycling. Can write a method, in this method to release the reference resources can be, this method can be arbitrarily named, of course, more canonical is inherited IDisposable to implement the disposable method.
For example, to release the requested managed and unmanaged resources in this method, the Objectbase class now becomes as follows:
public class objectbase:idisposable
{
~objectbase ()
{
Console.WriteLine ("Dispose Finish");
}
<summary> performs an application-defined task associated with releasing or resetting an unmanaged resource. </summary>
public void Dispose ()
{
}
}
Now there is another problem, and some users invoke the OB. Dispose () frees both managed and unmanaged resources, and some users simply OB = null nothing is done waiting for the system to be garbage collected. Can there be a more unified approach? Of course, we do not write the logic of freeing the resources in the Dispose () method, but rather in another method, such as Dispose (bool disposing), which allows the user to invoke the call, or the destructor calls this method to release the resource at the same time. There is also a problem when the user actively calls Dispose (), in fact, the Dispose (bool disposing) was executed two times (the active invocation, the destructor once) we add an identity, mark he can only be marked once to prevent multiple calls.
public class Objectbase:idisposable
{
private bool disposed = false;
~objectbase ()
{
Dispose (FALSE);
}
<summary> performs an application-defined task associated with releasing or resetting an unmanaged resource. </summary>
public void Dispose ()
{
Dispose (TRUE);
}
private void Dispose (bool disposing)
{
if (!disposed)
{
}
disposed = true;
}
}
Go ahead, why is Dispose (bool disposing) passing in a variable of type bool? In fact, this variable is marked to be safe to release, managed resources are reclaimed by the garbage collection mechanism, when the destructor is executed, the object it refers to may have been recycled, such as to fetch the list, and then execute clear when the error will certainly be, because the list has been recycled. When the user calls the Dispose interface, the object has not yet triggered a garbage collection, can be arbitrary to clear, so the logic will become:
public class Objectbase:idisposable
{
private bool disposed = false;
~objectbase ()
{
Dispose (FALSE);
}
<summary> performs an application-defined task associated with releasing or resetting an unmanaged resource. </summary>
public void Dispose ()
{
Dispose (TRUE);
}
private void Dispose (bool disposing)
{
if (!disposed)
{
if (disposing)
{
Releasing managed resources
}
Releasing unmanaged Resources
}
disposed = true;
}
}
There is also a problem: releasing unmanaged logic when the user actively calls Dispose two times (one active call, one destructor) then let's tell the system not to recycle the object to avoid two executions, thus releasing the logical completion of the interface:
public class Objectbase:idisposable
{
private bool disposed = false;
~objectbase ()
{
Dispose (FALSE);
}
<summary> performs an application-defined task associated with releasing or resetting an unmanaged resource. </summary>
public void Dispose ()
{
Dispose (TRUE);
Gc. SuppressFinalize (this);
}
private void Dispose (bool disposing)
{
if (!disposed)
{
if (disposing)
{
Releasing managed resources
}
Releasing unmanaged Resources
}
disposed = true;
}
}
But the user is too inconvenient to use, we encapsulate, can inherit the class convenient use. Because the release of managed resources is very frequent in C #, the majority of unmanaged resources are encapsulated in very few cases, and we individually encapsulate the interfaces as mandatory overrides and Overridable.
Public abstract class Objectbase:idisposable
{
private bool disposed = false;
~objectbase ()
{
Dispose (FALSE);
}
<summary> performs an application-defined task associated with releasing or resetting an unmanaged resource. </summary>
public void Dispose ()
{
Dispose (TRUE);
Gc. SuppressFinalize (this);
}
private void Dispose (bool disposing)
{
if (!disposed)
{
if (disposing)
{
Disposemanaged ();
}
Disposeunmanaged ();
}
disposed = true;
}
protected abstract void disposemanaged ();//Release managed resources
protected virtual void disposeunmanaged ()//release unmanaged Resources
{
}
}