C# static constructors, destructors
Spent some more time on the C# logging class I’ve been working on. Per Joe’s suggestions, I modified the StreamWriter so that it is now a class variable and as such, it need not be initialized every time the class is used. Instead, you can use a static constructor (the idea exists in both C# and Java, although they go by different names). In C#, you simply append the keyword ’static’ to the class name:
public class Logger {
static Logger() {
// insert static resource initialization code here
}
}
In Java it’s called a static initialization block (more here) and it looks like this:
public class Logger {
static {
// insert static resource initialization code here
}
}
If you’d like a real life example of a Java static initialization block, check out the source for the LogManager class in the log4j package.
Anyway, now the Logger class declares a StreamWriter:
private static StreamWriter sw;
and then uses the static constructor to initialize it for writing to the text file:
static Logger() {
// load the logging path
// ...
// if the file doesn't exist, create it
// ...
// open up the streamwriter for writing..
sw = File.AppendText(logDirectory);
}
Then use the lock keyword when writing to the resource to make sure that multiple threads can access the resource:
...
lock(sw) {
sw.Write("\r\nLog Entry : ");
...
sw.Flush();
}
Now all objects that call the various static methods will be using the same private streamwriter. But you’re left with one more problem. The streamwriter is never explicitly closed. If the StreamWriter was an instance variable, then we could solve this by implementing a destructor. The destructor would take this form:
~ Logger() {
try {
sw.Close();
} catch {
// do nothing, exit..
}
}
However, in this case the StreamWriter is a static/class variable, no ‘instance’ of Logger ever exists in the system, the ~Logger destructor will never get called. Instead, when the StreamWriter is eligible for destruction the garbage collector runs the StreamWriter’s Finalize method (which itself will then presumably call the Close() method of the StreamWriter instance), which will then automatically free up the resources used by the StreamWriter.
I updated the Logger class and it’s personal testing assistant TestLogger (which has also been updated to use 3 threads). You can download them here:
6 Comments