// This function kills the object with the name passed // in the parameter. It is called recursively through // the entire hierarchy. It returns true if the object // was killed, false otherwise. public bool KillChildNamed(string name) { // Check to see if m_child is nothing if (m_Child != null) { // Check to see if the current child is the object // to be disposed of. if (m_Child.Name == name) { // Kill m_Child m_Child = null; return(true); } else { // try { to find object to kill by searching through // child hierarchy. m_Child.KillChildNamed(name); return(false); } } else { // We've reached the end of the chain and // didn't find the object so return false return(false); } }
// This subroutine creates a hierarchy of OBJECT_DEPTH + 1 objects -- the // main object, and OBJECT_DEPTH children private void btnCreateObjects_Click(object sender, System.EventArgs e) { // Test for existence of m_TextObject. Only allow the user to create // one object tree at a time. if (m_TestObject == null) { // Output activity to log. this.AddToActivityLog(" -- Creating Object Tree -- "); // Create the test object. This will automatically create the // object hierarchy since the GcTest constructor automatically // calls itself recursively OBJECT_DEPTH number of times. m_TestObject = new GcTest("TestObject", OBJECT_DEPTH); // Add an event handler to handle the information events that // are raised by the GcTest object m_TestObject.ObjectGcInfo += new GcTest.InfoEventHandler(myObjectEventHandler); // Show the generation numbers and display them in the activity log. // Output the ArrayList strings (Generations) to the Activity Log foreach (Object myObject in m_TestObject.GetSelfAndChildGenerations()) { AddToActivityLog(myObject.ToString()); } // Redisplay the object hierarchy in the ListBox ShowTestObjects(); } else { // Only let the user create one tree. Object exists so just // warn the user. MessageBox.Show("Please Kill existing objects before creating new objects.", this.Text); } }
// Ensure a constructor is created that accepts two parameters -- the // name of the object and the number of levels of child // elements that should be created. // new() is the keyword used to create a constructor in Visual Basic.NET. public GcTest(string name, int numLevels) { // Just set the name of the current object to the passed name parameter. m_Name = name; // Only objects declared using will receive this // event, since event handlers pointed to by AddHandler can only // be associated after the object is created. Since in this How-To, they // are created dynamically, this event won't be caught. if (ObjectGcInfo != null) { ObjectGcInfo(m_Name + " Created"); } // Ensure the object hierarchy isn't too deep, since it doesn't help with // understanding the Garbage Collector and it makes for // a messy user iterface. // Limit the number of levels to 5. if (numLevels > 5) { numLevels = 5; } // Begin by testing that the numLevels is greater than zero, so // that our hierarchy is limited. if it is greater than zero, then // create a child object, naming it the name of the current object // except prefixing it with an "*" to distinguish it. Also, be sure // to decrement the number of // levels (so that it doesn't create objects indefinitely). if (numLevels > 0) { m_Child = new GcTest("*" + m_Name, numLevels - 1); // ObjectGcInfo can be raised by the child object, well // this object, so ensure that the myChildHandler has been // associated with the child's ObjectGcInfo event. m_Child.ObjectGcInfo += new InfoEventHandler(myChildHandler); } }
// This subroutine disposes of the object selected in the lstCreatedObjects // ListBox. How the objects are Disposed depends on whether the // chkIsFinalizeSuppressed is checked. if it is checked, then the Dispose // method will suppress the finalization of the object and its children, // otherwise the garbage collector will run. // The way the Dispose method of the GcTest class is designed, it will Dispose // and kill each of its child objects, but will not kill itself. private void btnDisposeObject_Click(object sender, System.EventArgs e) { // Check to ensure that there is a selected item if (this.lstCreatedObjects.SelectedItem == null) { return; } // Get the name of the selected object from the ListBox string strName = this.lstCreatedObjects.SelectedItem.ToString(); // Output activity to log. AddToActivityLog(" -- Disposing of " + strName + " -- "); // Check to see what object is being Disposed. if it is not // the current object, then call the DisposeChildNamed() // subroutine to try to find the right object to dispose of. if (strName == this.m_TestObject.Name) { // Dispose of m_TestObject. m_TestObject.Dispose(chkIsFinalizeSuppressed.Checked); // Set it equal to null. m_TestObject = null; } else { // try { to find object to Dispose by searching through // child hierarchy. m_TestObject.DisposeChildNamed(strName, chkIsFinalizeSuppressed.Checked); } // Redisplay the object hierarchy in the ListBox. ShowTestObjects(); }
// This subroutine kills the object selected in the lstCreatedObjects // ListBox by setting it to null, which opens it up for Garbage // Collection. private void btnKillObject_Click(object sender, System.EventArgs e) { // Check to ensure that there is a selected item if (this.lstCreatedObjects.SelectedItem == null) { return; } // Get the name of the selected object from the ListBox string strName = this.lstCreatedObjects.SelectedItem.ToString(); // Output activity to log. this.AddToActivityLog(" -- Killing " + strName + " -- "); // Check to see what object is being killed. if it is not // the current object, then call the KillChildNamed() // subroutine to try to find the right object to kill. if (strName == this.m_TestObject.Name) { // Kill m_TestObject by setting it equal to null. m_TestObject = null; } else { // try { to find object to Dispose by searching through // child hierarchy. m_TestObject.KillChildNamed(strName); } // Redisplay the object hierarchy in the ListBox ShowTestObjects(); }
// Declare a Dispose method. public void Dispose(bool isFinalizeSupressed) { // if SuppressFinalize is requested, tell the Garbage Collector // to suppress the finalization of this object. This can dramatically // increase the performance of the garbage collector. if (isFinalizeSupressed) { System.GC.SuppressFinalize(this); } // Dispose of any Children and set them to null if (m_Child != null) { m_Child.Dispose(isFinalizeSupressed); m_Child = null; } // Raise event showing that the object was disposed. Include in // parenthesis the value of SuppressFinalize. ObjectGcInfo(m_Name + " Disposed (" + isFinalizeSupressed.ToString() + ")"); }