While I am writing FSSEngineHelper, I question was raised after I was asked to free a library which is loaded in static constructor – “How to release a unmanaged resource which is loaded by static constructor?”
In the managed code world, we don’t have to think about this because Garbage Collection will handle this properly. However, in the unmanaged world, GC won’t help to release the resource as well as Dispose() and destructor cannot do release job because they are either belong to a instance. GC won’t invoke the Dispose or destructor if there isn’t a instance in the runtime.
Thus, seems the only method to release the library is just to load and free it at the time you use it. I mean, call the load and free methods in pair when you invoking a API which is in the library. It is a boring job to copy and paste the same block of code into every static method, it also produce lots of redundant and make the code hard to maintenance.
Fortunately, I recently found that we can use a singleton pattern to resolve this problem. if there is a instance in manage world, GC will try to release it at a time we cannot control. That remind me that why not add a static instance which load the lib while it was instantiating and free the lib while it being recycled by GC? I immediately wrote a “prove of concept”:
// Prove of Concept
// TestClass can properly create the file and delete file when program is exited.
// TestClass2 can not delete the file when program is exited.
class TestClass
{
public static TestClass Instance = new TestClass();
public static bool IsCreated()
{
return Instance.bCreated;
}
private const string filePath = "c:\\test.txt";
private bool bCreated = false;
public TestClass()
{
bCreated = true;
File.Create(filePath); //Replace Loadlibray here
}
~TestClass()
{
File.Delete(filePath); //Free here
}
}
class TestClass2
{
public static bool bCreated = false;
private static string filePath = "c:\\test.txt";
static TestClass2()
{
bCreated = true;
File.Create(filePath);
}
// This block will never be invoked since there is no instance in this class
~TestClass2()
{
File.Delete(filePath);
}
}
I ran the prove of concept and found the file was properly deleted after the program exit. This technical’s advantage is enable us to properly free libs which is loaded in a static ctor. And the disadvantage is we cannot make sure when the lib is freed.
Thanks for your reading and hope this article is helpful for you.