diff --git a/.runsettings b/.runsettings
index 90d26e0..3d17b67 100644
--- a/.runsettings
+++ b/.runsettings
@@ -11,5 +11,6 @@
Verbose
False
+ --forcegc
\ No newline at end of file
diff --git a/Tests/NFUnitTestClasses/UnitTestDestructorTests.cs b/Tests/NFUnitTestClasses/UnitTestDestructorTests.cs
index 97d94e4..7b7bcb1 100644
--- a/Tests/NFUnitTestClasses/UnitTestDestructorTests.cs
+++ b/Tests/NFUnitTestClasses/UnitTestDestructorTests.cs
@@ -6,8 +6,6 @@
using nanoFramework.TestFramework;
using System;
-using System.Diagnostics;
-using System.Reflection;
namespace NFUnitTestClasses
{
@@ -15,92 +13,102 @@ namespace NFUnitTestClasses
class UnitTestDestructorTests
{
// Removing as using something out of mscorlib
- //[TestMethod]
- //public void Destructors3_Test()
- //{
- // //Ported from Destructors3.cs
- // // Section 10.11
- // // Destructors implement the actions required to
- // // destruct the instances of a class.
- // //
- // // Note: This test may fail due to lengthy garbage collection, look for Destructor messages in later logs
- // Assert.IsTrue(DestructorsTestClass3.testMethod());
- //}
-
- //[TestMethod]
- //public void Destructors4_Test()
- //{
- // //Ported from Destructors4.cs
- // // Section 10.11
- // // Destructors implement the actions required to
- // // destruct the instances of a class.
- // //
- // // Note: This test may fail due to lengthy garbage collection, look for Destructor messages in later logs
- // Assert.IsTrue(DestructorsTestClass4.testMethod());
- //}
-
- // Removed as using a class out of mscorlib
- //[TestMethod]
- //public void Destructors7_Test()
- //{
- // //Ported from Destructors7.cs
- // // Section 10.12
- // // Destructors are not inherited. Thus, a class
- // // has no other destructors than those that are
- // // actually declared in the class.
- // //
- // // Note: This test may fail due to lengthy garbage collection, look for Destructor messages in later logs
- // Assert.IsTrue(DestructorsTestClass7.testMethod());
- //}
-
- //class DestructorsTestClass3
- //{
-
- // static int intI = 1;
-
- // ~DestructorsTestClass3()
- // {
- // // Calling Destructor for Test Class 3
- // intI = 2;
- // }
-
- // public static bool testMethod()
- // {
- // DestructorsTestClass3 mc = new DestructorsTestClass3();
- // mc = null;
- // nanoFramework.Runtime.Native.GC.Run(true);
- // int sleepTime = 5000;
- // int slept = 0;
- // while (intI != 2 && slept < sleepTime)
- // {
- // System.Threading.Thread.Sleep(10);
- // slept += 10;
- // }
- // // Thread has slept for
- // OutputHelper.WriteLine(slept.ToString());
- // if (intI == 2)
- // {
- // return true;
- // }
- // else
- // {
- // return false;
- // }
- // }
- //}
-
-
- class DestructorsTestClass4_Base
+ [TestMethod]
+ public void Destructors3_Test()
+ {
+ //Ported from Destructors3.cs
+ // Section 10.11
+ // Destructors implement the actions required to
+ // destruct the instances of a class.
+ //
+ // Note: This test may fail due to lengthy garbage collection, look for Destructor messages in later logs
+ Assert.IsTrue(DestructorsTestClass3.TestMethod());
+ }
+
+ [TestMethod]
+ public void Destructors4_Test()
+ {
+ //Ported from Destructors4.cs
+ // Section 10.11
+ // Destructors implement the actions required to
+ // destruct the instances of a class.
+ //
+ // Note: This test may fail due to lengthy garbage collection, look for Destructor messages in later logs
+ Assert.IsTrue(DestructorsTestClass4.TestMethod());
+ }
+
+ [TestMethod]
+ public void Destructors7_Test()
+ {
+ //Ported from Destructors7.cs
+ // Section 10.12
+ // Destructors are not inherited. Thus, a class
+ // has no other destructors than those that are
+ // actually declared in the class.
+ //
+ // Note: This test may fail due to lengthy garbage collection, look for Destructor messages in later logs
+ Assert.IsTrue(DestructorsTestClass7.TestMethod());
+ }
+
+ public class DestructorsTestClass3
+ {
+ static int intI = 1;
+
+ ~DestructorsTestClass3()
+ {
+ // Calling Destructor for Test Class 3
+ intI = 2;
+
+ Console.WriteLine("Calling Destructor for Test Class 3");
+ }
+
+ public static bool TestMethod()
+ {
+ DestructorsTestClass3 mc = new DestructorsTestClass3();
+ mc = null;
+
+ // the following call has been "replaced" with the setting commanding a GC run before new allocations, which will have the desired effect of
+ // nanoFramework.Runtime.Native.GC.Run(true);
+
+ int sleepTime = 5000;
+ int slept = 0;
+
+ while (intI != 2 && slept < sleepTime)
+ {
+ // force GC run caused by memory allocation
+ var dummyArray = new byte[1024 * 1024 * 1];
+
+ System.Threading.Thread.Sleep(10);
+ slept += 10;
+ }
+
+ // Thread has slept for
+ OutputHelper.WriteLine($"Thread as slept for{slept}");
+
+ if (intI == 2)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ public class DestructorsTestClass4_Base
{
public static int intI = 2;
~DestructorsTestClass4_Base()
{
- intI = intI * 2;
// Calling Destructor for Test Class 4 Base
+ intI = intI * 2;
+
+ Console.WriteLine("Calling Destructor for Test Class 4 Base");
}
}
- class DestructorsTestClass4 : DestructorsTestClass4_Base
+ public class DestructorsTestClass4 : DestructorsTestClass4_Base
{
~DestructorsTestClass4()
@@ -109,20 +117,29 @@ class DestructorsTestClass4 : DestructorsTestClass4_Base
// Calling Destructor for Test Class 4
}
- public static bool testMethod()
+ public static bool TestMethod()
{
DestructorsTestClass4 mc = new DestructorsTestClass4();
mc = null;
+
+ // the following call has been "replaced" with the setting commanding a GC run before new allocations, which will have the desired effect of
// nanoFramework.Runtime.Native.GC.Run(true);
+
int sleepTime = 5000;
int slept = 0;
+
while (intI != 8 && slept < sleepTime)
{
+ // force GC run caused by memory allocation
+ var dummyArray = new byte[1024 * 1024 * 1];
+
System.Threading.Thread.Sleep(10);
slept += 10;
}
+
// Thread has slept for
- OutputHelper.WriteLine(slept.ToString());
+ OutputHelper.WriteLine($"Thread as slept for{slept}");
+
if (intI == 8)
{
return true;
@@ -134,34 +151,45 @@ public static bool testMethod()
}
}
- class DestructorsTestClass7_Base
+ public class DestructorsTestClass7_Base
{
public static int intI = 2;
}
- class DestructorsTestClass7 : DestructorsTestClass7_Base
+ public class DestructorsTestClass7 : DestructorsTestClass7_Base
{
~DestructorsTestClass7()
{
- intI = 3;
// Calling Destructor for Test Class 7
+ intI = 3;
+
+ Console.WriteLine("Calling Destructor for Test Class 7");
}
- public static bool testMethod()
+ public static bool TestMethod()
{
DestructorsTestClass7 mc = new DestructorsTestClass7();
mc = null;
+
+ // the following call has been "replaced" with the setting commanding a GC run before new allocations, which will have the desired effect of
//nanoFramework.Runtime.Native.GC.Run(true);
+
int sleepTime = 5000;
int slept = 0;
+
while (intI != 3 && slept < sleepTime)
{
+ // force GC run caused by memory allocation
+ var dummyArray = new byte[1024 * 1024 * 1];
+
System.Threading.Thread.Sleep(10);
slept += 10;
}
+
// Thread has slept for
- OutputHelper.WriteLine(slept.ToString());
+ OutputHelper.WriteLine($"Thread as slept for{slept}");
+
if (intI == 3)
{
return true;
diff --git a/Tests/NFUnitTestSystemLib/UnitTestGCTest.cs b/Tests/NFUnitTestSystemLib/UnitTestGCTest.cs
index 1f017a3..18358d7 100644
--- a/Tests/NFUnitTestSystemLib/UnitTestGCTest.cs
+++ b/Tests/NFUnitTestSystemLib/UnitTestGCTest.cs
@@ -6,20 +6,19 @@
using nanoFramework.TestFramework;
using System;
-using System.Diagnostics;
namespace NFUnitTestSystemLib
{
[TestClass]
- class UnitTestGCTest
+ public class UnitTestGCTest
{
- class FinalizeObject
+ internal class FinalizeObject
{
public static FinalizeObject m_currentInstance = null;
~FinalizeObject()
{
- if (m_hasFinalized1 == false)
+ if (!m_hasFinalized1)
{
// First finalization
@@ -46,130 +45,178 @@ class FinalizeObject
static bool m_hasFinalized2 = false;
static bool m_Test1Result = false;
- //[TestMethod]
- //public void SystemGC1_Test()
- //{
- // ///
- // /// 1. Create a FinalizeObject.
- // /// 2. Release the reference
- // /// 3. Allow for GC
- // /// 4. Run ReRegisterForFinalize
- // /// 5. Allow for GC
- // /// 6. Verify that object has been collected
- // ///
- // ///
- // // Tests ReRegisterForFinalize
- // // Create a FinalizeObject.
- // FinalizeObject mfo = new FinalizeObject();
- // m_hasFinalized1 = false;
- // m_hasFinalized2 = false;
-
- // // Release reference
- // mfo = null;
-
- // // Allow GC
- // GC.WaitForPendingFinalizers();
- // int sleepTime = 1000;
- // int slept = 0;
- // while (m_hasFinalized1 == false && slept < sleepTime)
- // {
- // System.Threading.Thread.Sleep(10);
- // slept += 10;
- // }
- // OutputHelper.WriteLine("GC took " + slept);
-
- // // At this point mfo will have gone through the first Finalize.
- // // There should now be a reference to mfo in the static
- // // FinalizeObject.m_currentInstance field. Setting this value
- // // to null and forcing another garbage collection will now
- // // cause the object to Finalize permanently.
- // // Reregister and allow for GC
- // FinalizeObject.m_currentInstance = null;
- // GC.WaitForPendingFinalizers();
- // sleepTime = 1000;
- // slept = 0;
- // while (m_hasFinalized2 == false && slept < sleepTime)
- // {
- // System.Threading.Thread.Sleep(10);
- // slept += 10;
- // }
- // OutputHelper.WriteLine("GC took " + slept);
-
- // m_Test1Result = m_hasFinalized2;
- // Assert.IsTrue(m_hasFinalized2);
- //}
-
- //[TestMethod]
- //public void SystemGC2_Test()
- //{
- // ///
- // /// 1. Create a FinalizeObject.
- // /// 2. Release the reference
- // /// 3. SupressFinalize
- // /// 3. Allow for GC
- // /// 6. Verify that object has not been collected
- // ///
- // ///
- // // Tests SuppressFinalize
- // // Create a FinalizeObject.
- // FinalizeObject mfo = new FinalizeObject();
- // m_hasFinalized1 = false;
- // m_hasFinalized2 = false;
-
- // // Releasing
- // System.GC.SuppressFinalize(mfo);
- // mfo = null;
-
- // // Allow GC
- // GC.WaitForPendingFinalizers();
- // int sleepTime = 1000;
- // int slept = 0;
- // while (m_hasFinalized1 == false && slept < sleepTime)
- // {
- // System.Threading.Thread.Sleep(10);
- // slept += 10;
- // }
- // OutputHelper.WriteLine("GC took " + slept);
-
- // Assert.IsFalse(m_hasFinalized1);
- //}
-
- //[TestMethod]
- //public void SystemGC3_Test()
- //{
- // ///
- // /// 1. Create a FinalizeObject.
- // /// 2. Release the reference
- // /// 3. SupressFinalize
- // /// 3. Allow for GC
- // /// 6. Verify that object has not been collected
- // ///
- // ///
- // // Tests WaitForPendingFinalizers, dependant on test 1
- // // will auto-fail if test 1 fails.
- // Assert.IsTrue(m_Test1Result);
-
- // // Create a FinalizeObject.
- // FinalizeObject mfo = new FinalizeObject();
- // m_hasFinalized1 = false;
- // m_hasFinalized2 = false;
-
- // // Releasing
- // mfo = null;
-
- // // Wait for GC
- // GC.WaitForPendingFinalizers();
- // System.GC.WaitForPendingFinalizers();
-
- // // Releasing again
- // FinalizeObject.m_currentInstance = null;
-
- // // Wait for GC
- // GC.WaitForPendingFinalizers();
- // System.GC.WaitForPendingFinalizers();
-
- // Assert.IsTrue(m_hasFinalized2);
- //}
+ [TestMethod]
+ public void SystemGC1_Test()
+ {
+ ///
+ /// 1. Create a FinalizeObject.
+ /// 2. Release the reference
+ /// 3. Allow for GC
+ /// 4. Run ReRegisterForFinalize
+ /// 5. Allow for GC
+ /// 6. Verify that object has been collected
+ ///
+ ///
+ // Tests ReRegisterForFinalize
+ // Create a FinalizeObject.
+ FinalizeObject mfo = new FinalizeObject();
+ m_hasFinalized1 = false;
+ m_hasFinalized2 = false;
+
+ // Release reference
+ mfo = null;
+
+ // Allow GC
+ GC.WaitForPendingFinalizers();
+
+ int sleepTime = 1000;
+ int slept = 0;
+
+ while (!m_hasFinalized1 && slept < sleepTime)
+ {
+ // force GC run caused by memory allocation
+ var dummyArray = new byte[1024 * 1024 * 1];
+
+ System.Threading.Thread.Sleep(10);
+ slept += 10;
+ }
+
+ OutputHelper.WriteLine($"GC took {slept}");
+
+ // At this point mfo will have gone through the first Finalize.
+ // There should now be a reference to mfo in the static
+ // FinalizeObject.m_currentInstance field. Setting this value
+ // to null and forcing another garbage collection will now
+ // cause the object to Finalize permanently.
+ // Reregister and allow for GC
+ FinalizeObject.m_currentInstance = null;
+
+ GC.WaitForPendingFinalizers();
+
+ sleepTime = 1000;
+ slept = 0;
+
+ while (!m_hasFinalized2 && slept < sleepTime)
+ {
+ // force GC run caused by memory allocation
+ var dummyArray = new byte[1024 * 1024 * 1];
+
+ System.Threading.Thread.Sleep(10);
+ slept += 10;
+ }
+
+ OutputHelper.WriteLine($"GC took {slept}");
+
+ m_Test1Result = m_hasFinalized2;
+ Assert.IsTrue(m_hasFinalized2);
+ }
+
+ [TestMethod]
+ public void SystemGC2_Test()
+ {
+ ///
+ /// 1. Create a FinalizeObject.
+ /// 2. Release the reference
+ /// 3. SupressFinalize
+ /// 3. Allow for GC
+ /// 6. Verify that object has not been collected
+ ///
+ ///
+ // Tests SuppressFinalize
+ // Create a FinalizeObject.
+ FinalizeObject mfo = new FinalizeObject();
+ m_hasFinalized1 = false;
+ m_hasFinalized2 = false;
+
+ // Releasing
+ GC.SuppressFinalize(mfo);
+ mfo = null;
+
+ // Allow GC
+ GC.WaitForPendingFinalizers();
+
+ int sleepTime = 1000;
+ int slept = 0;
+
+ while (!m_hasFinalized1 && slept < sleepTime)
+ {
+ // force GC run caused by memory allocation
+ var dummyArray = new byte[1024 * 1024 * 1];
+
+ System.Threading.Thread.Sleep(10);
+ slept += 10;
+ }
+ OutputHelper.WriteLine($"GC took {slept}");
+
+ Assert.IsFalse(m_hasFinalized1);
+ }
+
+ [TestMethod]
+ public void SystemGC3_Test()
+ {
+ ///
+ /// 1. Create a FinalizeObject.
+ /// 2. Release the reference
+ /// 3. SupressFinalize
+ /// 3. Allow for GC
+ /// 6. Verify that object has not been collected
+ ///
+ ///
+
+ // Tests WaitForPendingFinalizers, dependant on test 1
+ // will auto-fail if test 1 fails.
+ OutputHelper.Write("Tests WaitForPendingFinalizers, dependant on test 1");
+ OutputHelper.WriteLine("will auto-fail if test 1 fails.");
+
+ Assert.IsTrue(m_Test1Result);
+
+ // Create a FinalizeObject.
+ FinalizeObject mfo = new FinalizeObject();
+ m_hasFinalized1 = false;
+ m_hasFinalized2 = false;
+
+ // Releasing
+ mfo = null;
+
+ int sleepTime = 1000;
+ int slept = 0;
+
+ while (!m_hasFinalized1 && slept < sleepTime)
+ {
+ // force GC run caused by memory allocation
+ var dummyArray = new byte[1024 * 1024 * 1];
+
+ System.Threading.Thread.Sleep(10);
+ slept += 10;
+ }
+
+ OutputHelper.WriteLine($"GC took {slept}");
+
+ // Wait for GC
+ GC.WaitForPendingFinalizers();
+
+ // Releasing again
+ FinalizeObject.m_currentInstance = null;
+
+ sleepTime = 1000;
+ slept = 0;
+
+ while (!m_hasFinalized2 && slept < sleepTime)
+ {
+ // force GC run caused by memory allocation
+ var dummyArray = new byte[1024 * 1024 * 1];
+
+ System.Threading.Thread.Sleep(10);
+ slept += 10;
+ }
+
+ OutputHelper.WriteLine($"GC took {slept}");
+
+ // Wait for GC
+ GC.WaitForPendingFinalizers();
+
+ Assert.IsTrue(m_hasFinalized2);
+ }
}
}