From this thread, Dispose()
must be explicitly called for disposable objects.
What happens when a Windows Service stops? Are the resources used by these objects automatically freed? Or should they be disposed before the service stops like this:
public void Stop()
{
cancellationTokenSource.Cancel();
waitForAllTasksToExit();
cancellationTokenSource.Dispose();
}
"It's a good practice to dispose", "They should be freed when the service stops" is what I think too. But is there a concrete answer with reference to the documentation?
If you access unmanaged resources (e.g. files, database connections etc.) in a class, you should implement IDisposable and overwrite the Dispose method to allow you to control when the memory is freed.
The dispose pattern is used for objects that implement the IDisposable interface, and is common when interacting with file and pipe handles, registry handles, wait handles, or pointers to blocks of unmanaged memory. This is because the garbage collector is unable to reclaim unmanaged objects.
Dispose() will not be called automatically. If there is a finalizer it will be called automatically. Implementing IDisposable provides a way for users of your class to release resources early, instead of waiting for the garbage collector.
To free and reset the resources that are unmanaged like connections to the databases, files, etc., and to perform a cleanup of the memory, we make use of a function called dispose of () function in C#. The dispose() function in C# must implement the IDisposable interface.
It depends on what are "resources used by these objects". Dispose
method itself won't be called on process exit, but most objects that contain "unmanaged" resources in addition to Dispose
also have finalizer. Finalizer will be called on process exit, but it might not be called on process crash. Now, on process exit (or crash) the following happens:
Any resources allocated by the process are freed.
All kernel objects are closed.
Kernel objects are for example file handles, sockets and so on. So even if process crashed and finalizers are not run (or there was no finalizer at all) - things like files or database\network connections will still be closed by OS.
You might have broader definition of unmanaged resource. Unmanaged means not managed by .NET Framework garbage collector. If I for example create a file on disk when creating some object and going to delete this file when this object is disposed - you might say this is also "unmanaged" resource. Such resource is not known to OS and it will not be "cleaned" if I've not implemented finalizer or finalizer was not called because of process crash.
All in all - if object implements IDisposable
- dispose it even before process exit. You might not know the intentions of that object developer, whether it has a finalizer or not - so it's better to always explicitly dispose it even before process exit.
@Evk already gave an answer, but it wasn't completely clear for me. After an extensive search through the documentation, I've compiled the following answer with reference to the documentation.
Long Answer:
When a Service stops, it's resources will be freed by the Garbage collector.
So what about the objects that implement IDisposable
? Will the unmanaged resources be freed? No. From Dispose Pattern:
The GC was specifically not designed to manage such unmanaged resources, which means that the responsibility for managing unmanaged resources lies in the hands of the developers.
So, what happens to the unmanaged resources? Are they never going to be freed?
There's still a chance
Object declares a virtual method Finalize (also called the finalizer) that is called by the GC before the object’s memory is reclaimed by the GC and can be overridden to release unmanaged resources.
This however has some drawbacks:
Although the documentation says that objects implementing IDisposable.Dispose
should either override the Finalize method or wrap the managed object in a SafeHandle so that if the consumer forgets to call Dispose
, the unmanaged resources are still freed; we could still end up in trouble.
From the Docs, the Finalize
method is called only if the derived type overrides it.
So, what if the developer has implemented neither of the 2 (Finalize
or SafeHandle
) above? Then we have a problem, there's no one to free the unmanged resources (at least the documentation doesn't say).
TLDR
The resources may or may not be freed (depending on circumstances explained above). So dispose all disposable objects (that are not disposed yet) in the Stop
method of your service.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With