Pergunta

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?

Foi útil?

Solução 3

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.

Outras dicas

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

  1. The system which is evicting the values and calling Dispose must use synchronization to ensure the calls don't overlap
  2. 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

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top