Thread safe disposable - c#

I need to ensure thread safety when disposing an IDisposable resource. The resource is cached multiple times in memory. When entries are evicted from the cache we have a callback that calls Dispose().
Therefore if the resource is cached three times, we'll call Dispose() three times.
Is it the responsibility of the IDisposable resource to ensure thread safety or the caller?

It is the responsibility of the class implementing the IDisposable interface to ensure that the method can be called multiple times without throwing exception.
To help ensure that resources are always cleaned up appropriately, a Dispose method should be callable multiple times without throwing an exception.
http://msdn.microsoft.com/en-us/library/fs2xkftw(v=vs.110).aspx
After an object is disposed, calls that fail because the object is disposed can and likely should throw an ObjectDisposedException (to aid in future debugging). If it is important that external objects know whether or not an object is disposed before making calls (because the object is shared), then it is customary to add a public boolean property (IsDisposed/Disposed) that indicates the state of the object.
EDIT: To more clearly cast this answer to the phrasing of the question, the class implementing IDisposable should implementing thread-safety if it is expected the class will be used in a cross-threaded environment. The link I posted shows an example of this at the bottom of the page.

Either
The system which is evicting the values and calling Dispose must use synchronization to ensure the calls don't overlap
The object itself must implement Dispose in such a way that it can be safely called from multiple threads
Both of these are completely valid solutions to the problem. Which one is better will depend a lot on your system.
All other things being equal I would opt for #2. I prefer to have my objects be self sufficient and require as little help as possible to successfully execute in the environment they are designed for. Making it thread safe reduces the knowledge the rest of the system needs to use it correctly

The answer depends on whether the objects you want to dispose adhere to the guidelines or not.
If they do some things get simpler, from IDisposable.Dispose:
If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.
So if calling Dispose multiple times has no effect other than the first time it's called you only have to ensure that you don't call them at the same time. And that should absolutely be the responsibility of the caller.
Stephen Cleary wrote an article on CodeProject about how to implement IDisposable and the possible problems which I find extremely helpful.

Is it the responsibility of the IDisposable resource to ensure thread safety or the caller?
It is up to the caller to guarantee thread safety through lock primitive or Monitor class IDisposable has nothing to do with thread safety. It's just a signal that the object's instance is ready to be garbage collected.

Related

Disposing MemoryCache in Finalizer throws AccessViolationException

EDIT
See edit note at the bottom of the question for additional detail.
Original question
I have a CacheWrapper class which creates and holds onto an instance of the .NET MemoryCache class internally.
MemoryCache hooks itself into AppDomain events, so it will never be garbage-collected unless it is explicitly disposed. You can verify this with the following code:
Func<bool, WeakReference> create = disposed => {
var cache = new MemoryCache("my cache");
if (disposed) { cache.Dispose(); }
return new WeakReference(cache);
};
// with false, we loop forever. With true, we exit
var weakCache = create(false);
while (weakCache.IsAlive)
{
"Still waiting...".Dump();
Thread.Sleep(1000);
GC.Collect();
GC.WaitForPendingFinalizers();
}
"Cleaned up!".Dump();
Because of the behavior, I believe that my MemoryCache instance should be treated as an unmanaged resource. In other words, I should ensure that it is disposed in the finalizer of CacheWrapper (CacheWrapper is itself Disposable follows the standard Dispose(bool) pattern).
However, I am finding that this causes issues when my code runs as part of an ASP.NET app. When the application domain is unloaded, the finalizer runs on my CacheWrapper class. This in turn attempts to dispose the MemoryCache instance. This is where I run into issues. It seems that Dispose attempts to load some configuration information from IIS, which fails (presumably because I'm in the midst of unloading the app domain, but I'm not sure. Here's the stack dump I have:
MANAGED_STACK:
SP IP Function
000000298835E6D0 0000000000000001 System_Web!System.Web.Hosting.UnsafeIISMethods.MgdGetSiteNameFromId(IntPtr, UInt32, IntPtr ByRef, Int32 ByRef)+0x2
000000298835E7B0 000007F7C56C7F2F System_Web!System.Web.Configuration.ProcessHostConfigUtils.GetSiteNameFromId(UInt32)+0x7f
000000298835E810 000007F7C56DCB68 System_Web!System.Web.Configuration.ProcessHostMapPath.MapPathCaching(System.String, System.Web.VirtualPath)+0x2a8
000000298835E8C0 000007F7C5B9FD52 System_Web!System.Web.Hosting.HostingEnvironment.MapPathActual(System.Web.VirtualPath, Boolean)+0x142
000000298835E940 000007F7C5B9FABB System_Web!System.Web.CachedPathData.GetPhysicalPath(System.Web.VirtualPath)+0x2b
000000298835E9A0 000007F7C5B99E9E System_Web!System.Web.CachedPathData.GetConfigPathData(System.String)+0x2ce
000000298835EB00 000007F7C5B99E19 System_Web!System.Web.CachedPathData.GetConfigPathData(System.String)+0x249
000000298835EC60 000007F7C5BB008D System_Web!System.Web.Configuration.HttpConfigurationSystem.GetApplicationSection(System.String)+0x1d
000000298835EC90 000007F7C5BAFDD6 System_Configuration!System.Configuration.ConfigurationManager.GetSection(System.String)+0x56
000000298835ECC0 000007F7C63A11AE System_Runtime_Caching!Unknown+0x3e
000000298835ED20 000007F7C63A1115 System_Runtime_Caching!Unknown+0x75
000000298835ED60 000007F7C639C3C5 System_Runtime_Caching!Unknown+0xe5
000000298835EDD0 000007F7C7628D86 System_Runtime_Caching!Unknown+0x86
// my code here
Is there any known solution to this? Am I correct in thinking that I do need to dispose the MemoryCache in the finalizer?
EDIT
This article validates Dan Bryant's answer and discusses many of the interesting details. In particular, he covers the case of StreamWriter, which faces a similar scenario to mine because it wants to flush it's buffers upon disposal. Here's what the article says:
Generally speaking, finalizers may not access managed objects.
However, support for shutdown logic is necessary for
reasonably-complex software. The Windows.Forms namespace handles this
with Application.Exit, which initiates an orderly shutdown. When
designing library components, it is helpful to have a way of
supporting shutdown logic integrated with the existing
logically-similar IDisposable (this avoids having to define an
IShutdownable interface without any built-in language support). This
is usually done by supporting orderly shutdown when
IDisposable.Dispose is invoked, and an abortive shutdown when it is
not. It would be even better if the finalizer could be used to do an
orderly shutdown whenever possible.
Microsoft came up against this problem, too. The StreamWriter class
owns a Stream object; StreamWriter.Close will flush its buffers and
then call Stream.Close. However, if a StreamWriter was not closed, its
finalizer cannot flush its buffers. Microsoft "solved" this problem by
not giving StreamWriter a finalizer, hoping that programmers will
notice the missing data and deduce their error. This is a perfect
example of the need for shutdown logic.
All that said, I think that it should be possible to implement "managed finalization" using WeakReference. Basically, have your class register a WeakReference to itself and a finalize action with some queue when the object is created. The queue is then monitored by a background thread or timer which calls the appropriate action when it's paired WeakReference gets collected. Of course, you'd have to be careful that your finalize action doesn't inadvertantly hold onto the class itself, thus preventing collection altogether!
You can't Dispose managed objects in the finalizer, as they might have already been finalized (or, as you've seen here, portions of the environment may no longer be in the state you're expecting.) This means that if you contain a class which must be Disposed explicitly, your class must also be Disposed explicitly. There's no way to 'cheat' and make the Disposal automatic. Unfortunately, garbage collection is, in cases like this, a leaky abstraction.
I would suggest that objects with finalizers should generally not be exposed to the outside world, and should only hold strong references to things which are actually needed for finalization and are not exposed to anything in the outside world that is not expecting them to be used for that purpose. Public-facing types should not have finalizers themselves, but should instead encapsulate cleanup logic within privately-held instances of finalizable classes whose purpose is to encapsulate such logic.
The only time it really makes sense for a finalizer to attempt to clean up a resource which is owned by another object is when the other object is designed to interface with the finalizer. I can't think of any places where Framework classes have engineered in the proper hooks, but will offer an example how Microsoft could have engineered them to do so.
A File object could offer an event with thread-safe subscribe and unsubscribe methods which would fire (notifying the last subscriber first) when the File object receives either a Dispose call or a finalize request. The event would fire between the time Finalize is called and the time the encapsulated file is actually closed, and could be used by a an external buffering class as a signal that it needs to give the File any information which it has received but not yet passed along.
Note that to make such a thing work properly and safely, it would be necessary that the part of the File object which has the finalizer not be exposed to the public, and that it use a long weak reference to ensure that if it runs while the public-facing object is still alive, it will reregister itself for finalization. Note that if the only reference to a WeakReference object is stored in a finalizable object, its Target property may be invalidated if the finalizable object becomes eligible for finalization even if the actual target of the reference is still alive. Defective design, IMHO, and one which must be worked around somewhat carefully.
It's possible to design objects with finalizers that can cooperate (the easiest way to do it, generally, is to only have one object in the group sport a finalizer), but if things aren't designed to cooperate with finalizers, the best that one can do is generally have a finalizer sound an alarm indicating "This object wasn't supposed to be Disposed but wasn't; because it wasn't, resources are going to leak, and there's nothing to be done about it except fix the code to dispose the object properly in future".

When to return an object back to its pool

I want to use an object-pool in my C# application, and I know that there isn't any reference count in C#. If the same object can be passed to several threads, how can I know when there are no more references to the object so that I can return it to the object pool?
I thought of doing it in the dispose method, but that is too late, and it can't be returned to the pool since it is disposed.
Implementing object-pool in .Net can be done using a Finalizer.
Actually, most of the pools implemented in .Net are doing this also (for example - DB connection pool).
Using a finalizer allows you to know that the object isn't referenced anymore, as the finalizer is being called after the GC determine that there are not possible routes to the object.
The technique is not to do any destructive methods in your Dispose (i'll be getting this next) and finalize method.
Let's say that you have an PooledObject type, and an ObjectPool type that manages the pool.
In the ObjectPool, add an internal methods called ReturnToPool(PooledObject obj) that will get the object and make it available for other callers.
In the PooledObject type, you should add an internal method called ReleaseResources - which will only be called by the ObjectPool when the entire pool should be removed from memory - in this method you will implement your dispose logic (closing handles, releasing un-managed memory, etc..).
In the PooledObject Dispose and Finalize methods you should call the ReturnToPool methods in the ObjectPool (static, or internally stored in the pooled object) - this is called - resurrection.
When calling the ReturnToPool method in the finalizer you are actually resurrecting the object and making it available again.
Make sure you are re-registering PooledObject for finalization in the ReturnToPool method in ObjectPool - GC.ReRegisterForFinalize method.
Both of those types should be in the same assembly, of course. (to make sure they can call each other internal methods)
You should however implement the Dispose pattern either way. It will save time when object is not being used anymore (after leaving Using scope for example) and will return the object to the pool.
Hope this helps.
Ofir.
how can I know when there are no more references to the object so that I can return it to
the object pool.
Hm. You implement reference counting.
What also works is a proxy around it that has a Disposable method. WHen done with the Proxy, the dispose implementation puts the inner object to the pool (the outer object tuhs is VERY small).
But at the end you have to know when to release. This is called programming. This only makes sense for "fat" objets with significant initialization overhead, and then you really have to make sure you acutally know when to put them back by logic (i.e. custom counting etc.).
It should be in the Close/Release method. Responsibility of creating and disposing the instance lies with the ObjectPool itself.
To request/release an object from/to ObjectPool, use Open/Close or Acquire/Release.
A The Code Project article, C# Object Pooling, presents a nice lightweight custom object pool implementation.
You can also look at Connection Pooling Mechanism of ADO.NET to get hint of an object pooling example.

Are destructor methods used implicitly by the garbage collector, and dispose methods used by developers to explicitly dispose of objects?

I can see there's already a lot of threads regarding dispose vs. destructor methods but I just want to make sure that I'm understanding them correctly before I move on.
Are destructor methods used implicitly by the garbage collector for when objects are no longer referenced (i.e. no longer needed) and dispose methods used by us developers to explicitly dispose of objects that may not be handled by the garbage collector?
Also - I'm reading into all this now and it seems that it's a case of one or the other with these methods. So for example given the following code:
class DansClass : IDisposable
{
public void Dispose()
{
GC.SuppressFinalize(this);
Console.WriteLine("Disposing...");
}
-DansClass()
{
Console.WriteLine("Destructing...");
}
}
The output will be:
Destructing...
Understandable, as we've suppressed the finalize (destructor) so we only see the Dispose output.
But if I comment out the SuppressFinalize() method the output is:
Disposing...
Why isn't the destructor called as well?
Well the behavior you're seeing is because Finalizers (what you're refering to as a Destructor is also known as a Finalizer in .Net) are queued up to run in the background by the Garbage Collector.
Eventually it will be called (although in some instances it may not). You can force their execution, however, to understand what is going on:
// Assuming you remove the GC.SuppressFinalize call
myDisposable.Dispose();
GC.WaitForPendingFinalizers();
// Output:
// Disposing...
// Destructing...
You only need to implement the pattern when you have external resources, or encapsulate members which contain external resources. Finalizers should only be implemented when you have external, unmanaged resources.
Proper implementation of the IDisposable pattern requires:
Dispose cleans up both unmanaged and managed resources
Finalizer cleans up hanging, unmanaged resources (if none exist, it is not needed)
Neither may throw an exception, Dispose must be callable more than once
The Finalizer should call the Dispose implementation
Domain specific termination methods, like Close, should be functionally equivalent to Dispose if both exist
Dispose methods, finalizers, and C#'s ironically-named destructors, exist because many objects ask other entities to do things on their behalf until further notice (typically granting exclusive use of something like a file, a region of memory, communications stream, hardware device, GDI handle, etc.); if an object issuing such a request were to disappear without those other entities know their services are no longer required, anything that had been set aside on behalf of the abandoned object would remain uselessly inaccessible.
The IDisposable.Dispose method provides a nice consistent way of telling an object that it will no longer be asked to do anything would require the assistance of other entities, and that any other entities which were doing anything on its behalf should be told to stop doing so. If IDisposable.Dispose is called properly, objects can minimize the extent to which outside entities have to act on their behalf.
Unfortunately, for various reasons (most being easily avoidable; some not), objects are sometimes abandoned without IDisposable.Dispose having been called. This will result in outside entities having to uselessly keep acting, at least for awhile, on behalf of the objects which are abandoned. To avoid having outside entities act forever on behalf of outside entities, the system can notify objects that they have been abandoned, thus giving them a chance to inform outside entities of this fact. Whenever an object whose class overrides Object.Finalize is created, it will be placed in a special list of objects that want to be notified if they are abandoned. Existence on this list, by itself, is not enough to make an object be considered "live", but before the garbage collector removes dead objects from memory it will check whether they are on the notify-before-destruction list. All dead objects which are on the list will be moved from the list of objects requesting notification if/when they are abandoned to a list of objects needing to be notified that they have been abandoned. Placement on this second list will cause the dead objects, and any objects to which they hold references, to be considered "alive" again, at least until the notification has been performed. When they are moved to the second list, however, they are removed from the first list so that if they are later found to be dead again, they will be swept from memory without further notice.
After the garbage collection completes, if any objects are in the list of objects needing to be notified of abandonment, the system will call the Object.Finalize method of each such object. Typically, once Object.Finalize has been called on such an object, there won't be any more rooted references to it and it will vanish on the next garbage collection. It is possible, however, for objects to be resurrected.
In vb.net and, so far as I know, most .net languages, one overrides Object.Finalize by simply declaring an override in the usual fashion. For whatever reason, the creators of C# decided to forbid that. Instead, in C#, one must use a language structure, ironically called a "Destructor", to override Finalize so that objects which are found to be abandoned will not be destroyed without notice, but instead be given a chance to clean up.
There are many tricky wrinkles in the actual operation of Object.Finalize, and it is best to avoid relying upon it except when absolutely necessary. The ironically-named "destructors" don't actually destroy objects, but rather delay their destruction. Calling GC.SuppressFinalize() on an object will remove it from the list of objects requesting notification when they are abandoned; provided that Dispose is called on an object, and it in turn calls GC.SuppressFinalize() as its last operation, there isn't any particular harm in having an object override Finalize or declare a "destructor", but in general it's best to only override Finalize (or declare "destructors") in relatively simple classes.

IDisposable with destructor: requires thread-safe implementation?

This is pretty much only for me to make sure, I got this right:
We have a large resource class implementing the IDisposal pattern. It should (by design) be implemented in a way, that enables it to get called more than one time (even if we try to call it exactly one time of course). We also implement a finalizer, which also calls the Dispose() method - just as backup. If called manually, Dispose() will also call GC.SuppressFinalize(this).
There are several examples of disposal patterns around. Most of them call GC.SuppressFinalize(this) at the end of the disposing code. Some claim, it would be better, to call it at the beginning of the Dispose() method, before any cleaning. Latter argue, this would make sure, the GC doesn't call the finalizer concurrently, while we are still cleaning up.
Question:
It seems, placing GC.SuppressFinalize at the beginning doesn't do any better? We still have a race condition, right? So is it true, that we rather should implement Dispose() in a thread safe way instead?
The GC only cleans up objects that are not 'reachable'.
A class in which code is executing is still 'reachable' because it's this pointer is on the stack. So while dispose is executing, the finalizer won't be called.
So it does not matter if you call SuppressFinalize at the begin or end.
As commentors below indicated, the CLR implementation does not appear to guarantee that your object does not get garbage collected/finalized while instance methods are executing. The only possible 'dependable' reference keeping the object alive is the one used to invoke the method on the object, but I don't know enough about the JIT internals to make statements about that, and it's behaviour might change.
I'm leaving the answer here for access to the discussion below.
While it is sometimes possible for an object to be finalized while a seemingly-live reference exists, that can only happen when nothing else is going to ever refer to the object. The GC.SuppressFinalize(this) actively refers to the present object 'this', thus guaranteeing that it will not be finalized until the GC.SuppressFinalize executes. Further, the fact that the object reference existed to dispose the object, and was available to the Dispose method, guarantees that the finalizer couldn't have been queued before Dispose started running unless the object was dead and a finalizer somewhere (either its own finalizer, or that of some other object) resurrected it.
Because there are some scenarios where an object could be scheduled for finalization and resurrected without ever being aware of it, it may not be a bad idea to protect a dispose and finalize against redundant operation. Microsoft's pattern is not a good one, however. Finalizable objects shouldn't hold references to any objects not needed for finalization. If an object would hold a mixture of managed and unmanaged resources, the unmanaged resources should be moved into their own classes (effectively turning them into managed resources), so then the main object would hold nothing but managed resources.
Dispose should not throw any exceptions.
I would make sure all the code in Dispose is thread safe so that if it gets called it will not do anything strange. Usually adding checks if variables are null already should do the trick.
In the microsoft examples i've only seen GC.SuppressFinalize at the end of the Dispose function.

The cost of finalize in .Net

(1) I've read a lot of questions about IDisposable where the answers recommend not using Finalize unless you really need to because of the process time involved.
What I haven't seen is how much this cost is and how often it's paid. Every millisecond? second? hour, day etc.
(2) Also, it seems to me that Finalize is handy when its not always known if an object can be disposed. For instance, the framework font class. A control can't dispose of it because it doesn't know if the font is shared. The font is usually created at design time so the user won't know to dispose it, therefore finalize kicks in to finally get rid of it when there are no references left. Is that a correct impression?
The main problem with finalize is that it blocks an object from being garbage collected. Instead, the finalizer is called, and the object collected "on the next run". Well, technically IIRC the finalizer runs a list of objects in a separate thread. Anyhow, this is not an "every ms" issue, more an "multiple GC runs needed to get rid of the objects.
Finalize is conceptually different than Dispose. Finalize can only free unmanaged resources. Dispose can free managed and unmanaged resources. You should use each as appropriate. (Note that a class with a Finalizer should always implement IDisposable).
Dispose must be called explicitly; Finalize can only be called by the GC.
Update: See my blog post on How to Implement IDisposable and Finalizers: 3 Easy Rules.
I've got a blog post about IDisposable and Finalizing - not about the performance though.
I'll answer your second question.
No, Finalize should not be used in this manner. In fact, with the exception of only a very few fringe cases, you should only override Finalize (or declare a destructor in C#) if the class directly holds unmanaged resources.
The issue you described is one of ownership. The owner of an IDisposable class is responsible for its lifetime and the decision of when to call Dispose. Other parts of code are free to use that class, but since they cannot claim ownership they should not participate in the lifetime management of that class.
Unfortunately I am not very familiar with the Font class nor how it might relate to the specific scenario that was the impetus for your question, but I can make a general statement that might apply to you. If your code did not create the instance (via the constructor) directly then your code should not be considered the owner. In that case you can assume the responsibility for disposal is left to something else.
Finalize is extremely useful as a double check. If a crash or someone's bad code doesn't dispose your object before it goes out of scope, guarantee that its resources will be released in the finalizer.
You can do some fancy footwork in your disposer though by calling GC.SuppressFinalize(this) which will allow you to write a method which will work in both situations and give you a guarantee that the code will work nicely.
You could even fire an MDA if you were writing a framework to remind people that they should dispose your object.
The penalty of the finalizer is basically that you end up pushing your object into the level 2 queue which takes longer to run. If you are consistently using objects and they are finalizing this could result in a level 2 collection running more often than neccessary just to run your finalizer threads.

Categories