static destructor - c#

C# has static constructor which do some initialization (likely do some unmanaged resource initialization).
I am wondering if there is static destructor?

Not exactly a destructor, but here is how you would do it:
class StaticClass
{
static StaticClass() {
AppDomain.CurrentDomain.ProcessExit +=
StaticClass_Dtor;
}
static void StaticClass_Dtor(object sender, EventArgs e) {
// clean it up
}
}

This is the best way (ref: https://stackoverflow.com/a/256278/372666)
public static class Foo
{
private static readonly Destructor Finalise = new Destructor();
static Foo()
{
// One time only constructor.
}
private sealed class Destructor
{
~Destructor()
{
// One time only destructor.
}
}
}

No, there isn't.
A static destructor supposedly would run at the end of execution of a process. When a process dies, all memory/handles associated with it will get released by the operating system.
If your program should do a specific action at the end of execution (like a transactional database engine, flushing its cache), it's going to be far more difficult to correctly handle than just a piece of code that runs at the end of normal execution of the process. You have to manually handle crashes and unexpected termination of the process and try recovering at next run anyway. The "static destructor" concept wouldn't help that much.

No, there isn't. The closest thing you can do is set an event handler
to the DomainUnload event on the AppDomain and perform your cleanup there.

Initializing and cleaning up unmanaged resources from a Static implementation is quite problematic and prone to issues.
Why not use a singleton, and implement a Finalizer for the instance (an ideally inherit from SafeHandle)

No there is nothing like destructor for static classes but you can use Appdomain.Unloaded event if you really need to do something

Related

Self-closing StreamWriter singleton

I tried to further narrow down the problem in Flush StreamWriter at the end of its lifetime implementing a singleton-like self-closing StreamWriter:
class Foo : System.IO.StreamWriter
{
private static readonly Foo instance = new Foo( "D:/tmp/test" );
private Foo( string path )
: base( path )
{
}
~Foo()
{
this.Close();
}
public static Foo Instance
{
get
{
return instance;
}
}
}
The intended effect is that in a sample program like
class Program
{
private static void Main( string[] args )
{
Foo.Instance.Write( "asdf\n" );
}
}
the garbage collector causes the instance of Foo to be closed.
This does not work. Apparently, the StreamWriter is already gone when Foo's destructor runs, and I get a System.ObjectDisposedException.
How do I call Close() on the stream in an appropiate way and prevent loss of data?
Apparently, the StreamWriter is already gone when Foo's destructor runs
Yes. At program termination, assuming your object gets GC'ed at all (there's no guarantee it will be), the runtime doesn't provide any guarantees about the order in which it executes finalizers. Both objects are unreachable and eligible for finalization at the same time, and so their finalizers could run in any order.
Finalizers are there only as a backstop for buggy code. And they are not 100% reliable for that purpose either. It's why you should work hard to avoid buggy code.
You'll need a deterministic way to dispose the singleton object on process exit. You can put this into the control of your program's main logic, which is controlling the process lifetime, and have it dispose the singleton (e.g. via a public method you write for that purpose). Another alternative is to subscribe to the AppDomain.ProcessExit event in your singleton's constructor, and have the handler close the singleton there.
See these related questions for additional information:
How can I ensure that I dispose of an object in my singleton before the application closes?
Disposable singleton in C#

Does Dispose() get called if my app crashes?

I have a scenario where on application crash, I have to clear certain registry keys. I am trying to use Dispose() pattern for it. in case of application crash during garbage collection does the Dispose gets called to clear the registry???
Is there any other pattern to do such activities? I can not use Unhandled application handler as the code I want to call is not referenced directly by the Main application. I could use reflection but not sure if that's the right pattern.
any advise or experience in this matter will be really appreciated.
It sounds like you want to add an event handler to the AppDomain.UnhandledException event, do some processing (writing to the registry in this case) and then let the program die.
Assuming that you're not doing anything odd like loading your library into a different AppDomain you should be able to hook this from your library in a variety of ways. I've used a static constructor for this in the past and to hook the AssemblyResolve event from a library.
Something like this:
public static class CrashHandler
{
public static bool Initialized { get; private set; }
[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlAppDomain)]
static CrashHandler()
{
AppDomain.CurrentDomain.UnhandleException += crash_handler;
Initialized = true;
}
static void crash_handler(object sender, UnhandledExceptionEventArgs args)
{
// do your thing here
}
}
In order to get this to actually fire you need to read the Initialized value somewhere at least once. Add it to the constructor of one of your library objects that you can be sure will be instantiated early.

Can a static class know when it's being unloaded at application exit? [duplicate]

C# has static constructor which do some initialization (likely do some unmanaged resource initialization).
I am wondering if there is static destructor?
Not exactly a destructor, but here is how you would do it:
class StaticClass
{
static StaticClass() {
AppDomain.CurrentDomain.ProcessExit +=
StaticClass_Dtor;
}
static void StaticClass_Dtor(object sender, EventArgs e) {
// clean it up
}
}
This is the best way (ref: https://stackoverflow.com/a/256278/372666)
public static class Foo
{
private static readonly Destructor Finalise = new Destructor();
static Foo()
{
// One time only constructor.
}
private sealed class Destructor
{
~Destructor()
{
// One time only destructor.
}
}
}
No, there isn't.
A static destructor supposedly would run at the end of execution of a process. When a process dies, all memory/handles associated with it will get released by the operating system.
If your program should do a specific action at the end of execution (like a transactional database engine, flushing its cache), it's going to be far more difficult to correctly handle than just a piece of code that runs at the end of normal execution of the process. You have to manually handle crashes and unexpected termination of the process and try recovering at next run anyway. The "static destructor" concept wouldn't help that much.
No, there isn't. The closest thing you can do is set an event handler
to the DomainUnload event on the AppDomain and perform your cleanup there.
Initializing and cleaning up unmanaged resources from a Static implementation is quite problematic and prone to issues.
Why not use a singleton, and implement a Finalizer for the instance (an ideally inherit from SafeHandle)
No there is nothing like destructor for static classes but you can use Appdomain.Unloaded event if you really need to do something

Why not static destructors in C#

I am interested in knowing why static destructors are not allowed in C#. Note that I am not supposing that they exist in any other language.
I could have a class like this one.
class A
{
static A()
{
// here I can load a resource that will be avaliable for all instances
// of this class.
}
}
When the application ends I may need to release the resource.
So, the semantic of a static destructor could be the following: called when the application ends, for classes that contain it and were initialized in the app.
Your semantic is one possible one, but I guess you have not checked all effects it would have on the language. In most (more or less) dynamic languages I know, destruction is a much more complicated topic that it looks like. Why not call the destructor when the class is not referenced anymore? Or if the assembly is unloaded? In what order should destructor be called? ...?
If you just want to execute some code when the application ends, have a look at the .Net documentation. There are easier and more reliable ways to do so.
So, the semantic of a static destructor could be the following: - be
called when the application ends, on class that contains it and was
charged in the app.
Your semantic relies on your program doing an specific action at the end of execution and this is far more difficult to correctly handle than just a piece of code that runs at the end of normal execution of the process.
Think about transactions or file management operations. You have to manually handle crashes and unexpected termination of the process and try recovering at next run anyway, so then having an static destructor wouldn't help that much. .NET managed world favors upon using patterns instead of that. Now, if you're having serious problems with this, try to attach an event handler to the DomainUnloaded event on the AppDomain and perform your cleanup there.
You can, also, give a try to the singleton dispose way:
class A : IDisposable
{
public static A Instance {get; private set;}
public static A()
{
Instance=new A();
}
public void MethodA() {...}
public void Dispose()
{
//...
}
~A()
{
// Release your hard resources here
}
}
And then, use the safe method:
A.Instance.MethodA();

Destructor implemented via event

I have several objects in our framework, that by the requirement need to provide event ObjectTerminated. The user of the framework can subscribe to this event and clean-up some unmanaged stuff, that he is using. These objects are designed to exist the whole life time of the application, and I'm not controlling their life. You can think of them as an array of singletons.
I want to write code like this:
class SomeWorkflowControlObject
{
public event EventHandler<> ObjectTerminated;
~SomeWorkflowControlObject()
{
if (ObjectTerminated != null) ObjectTerminated(this, null);
}
}
I am not sure, am I allowed to do that. What could go possibly wrong with such solution?
Updated:
What about Process.GetCurrentProcess().Exited ? Can I use it in such manner?
You should not do this. Basically, destructors do not exist in C#. What you have written is a finalizer, and the only thing a finalizer should ever do is to free unmanaged resources.
You are not allowed to access any other managed object at all, since the garbage collector might already have removed it. I do not think your null check is a sufficient guard against this situation; that object reference might still point to your (event) delegate, even if it's already gone.
So in short, don't do this.
Alternatives:
Subscribe to the Application.ApplicationExit event if you have a Windows Forms application.
You might want to consider implementing the IDisposable interface instead and then do something like this:
public class SomethingVeryLongLived : IDisposable
{
…
}
…
public static void Main()
{
using (var sth = new SomethingVeryLongLived(…))
{
Application.Run(new SomeForm(…));
} // <-- at this point, foo.Dispose() is guaranteed to be called.
}
Take note that even in the case of using IDisposable, it's probably not a good idea / design to trigger an event inside the object that is getting disposed, since disposed objects should no longer be accessed.
For this very reason, I would recommend you do the following:
Use a try…finally block:
public static void Main()
{
var sth = new SomethingVeryLongLived(…);
try
{
Application.Run(new SomeForm(…));
}
finally
{
SomethingVeryLongLived.Terminate();
}
}
This would seem best to me because you are not abusing the IDisposable interface, and it's very clear what the code does... there's no hidden meaning.
I believe the design of that framework is inherently flawed. Let me explain:
1. [...] several objects in our framework, that by the requirement need to provide event ObjectTerminated.
This doesn't make sense. If an object has been terminated, as the event's name suggests, then I would assume that it is already gone and that I can no longer access it. This raises two questions:
How does something dead trigger an event? It's like a corpse talking to you from its grave, "I am dead." Do you really want this?
Why would anyone else be interested in reacting to such an event, if the event sender is no longer supposed to be there? What is there to clean up after the corpse has already been buried?
2. I'm not controlling their life.
Who is controlling their lifetime, then? Why isn't it their responsibility to do, or trigger, the necessary clean up work at the appropriate moment? Let me further elaborate on this very point:
3. [...] can subscribe to this event and clean-up some unmanaged stuff [...]
Where is this unmanaged stuff, and which object is responsible for handling it? If it is your own object, then why doesn't your object dispose of it — why do you instead want to trigger an event, so that someone else can dispose of the stuff? It's like me carrying out my neighbour's garbage, instead of him doing it himself. (I'm not talking about an old lady there.)
Your class would make much more sense if it looked like this:
class SomeWorkflowControlObject : IDisposable
{
// the following event doesn't make sense, sorry.
// public event EventHandler<> ObjectTerminated;
private IntPtr _handleToUnmanagedResource;
~SomeWorkflowControlObject()
{
Dispose(explicitly: false);
}
public void Dispose()
{
Dispose(explicitly: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool explicitly)
{
if (explicitly)
{
// free managed resources here; perhaps trigger an event 'Disposing'.
}
DisposeUnmanagedResource(_handleToUnmanagedResource);
}
}
That is, it is a wrapper around some unmanaged resource, for whose disposal it is responsible itself, and noone else. Thus, there is no longer a need to trigger an event, such that someone else can dispose the unmanaged resource, which should be hidden inside your object anyway.

Categories