Implementing and using IDisposable - c#

I'm working with a 3rd party object that implements IDisposable. In order to make it unit test "able" I build a wrapper. I understand that object implements IDisposable my wrapper needs to implement IDisposable as well.
public interface IWrapper : IDisposable
{
void Complete();
}
public class Wrapper : IWrapper
{
private readonly ThirdPartyLib lib;
public Wrapper()
{
lib = new ThirdPartyLib();
}
public void Complete()
{
lib.Comlete();
}
public void Dispose()
{
lib.Dispose();
}
}
public class Processor : IProcessor
{
private readonly IWrapper wrapper;
public Processor(IWrapper wrapper)
{
this.wrapper = wrapper;
}
public void Process()
{
// do some work
using (wrapper) {
// do more work
}
}
}
Suppose Processor is injected in some class that is using it and Process() is executed
What happends to wrapper if we call Process() again? - wouldn't ThirdPartyLib() throw an exception since it was created only once (in wrappers constructor) and now it has been disposed
Does it not get disposed as long as there is a reference to it?
Should the wrapper maybe be build in such a way that new() "ing" of ThirdPartyLib be performed not in a constructor but in a seperate method, say Begin() - like so:
public class Wrapper : IWrapper
{
private ThirdPartyLib lib;
public void Begin()
{
lib = new ThirdPartyLib();
}
public void Complete()
{
lib.Comlete();
}
public void Dispose()
{
lib.Dispose();
}
}
Then using it:
using (wrapper.Begin()) {

You're right to be concerned. Calling Process() twice would likely cause an exception. Not calling Process() at all would leave the object undisposed.
There is no simple rule for what you should do instead. There are multiple options, and which can be used depends on other parts of your code that aren't in your question.
If Processor takes a reference to an externally owned Wrapper, then it should not dispose that wrapper at all.
If Processor takes ownership of the Wrapper at construction time, then it should dispose that wrapper at dispose time. This means Processor should implement IDisposable as well.
If Processor can be modified to create a new Wrapper on demand, then that wrapper can be disposed when Process() is done with it.
Or, as you suggested, if Wrapper can be modified to create a ThirdPartyLib on demand, that could work too. But be careful: calling wrapper.Begin(); wrapper.Begin(); would leave one ThirdPartyLib undisposed and unreferenced. You'd need to restructure your API a bit more to prevent this from becoming a problem, and effectively, that would mean turning your Wrapper into a ThirdPartyLibFactory.

I think Processor should not dispose of IWrapper, because it is not the one that instantiated it and it doesn't know if it can be disposed or if it's being injected into other objects. In that case, Processor should not use using with wrapper.
The code to dispose of IWrapper should be in the class that instantiated it in the first place, since that's the one that knows about it's lifecycle.

Related

Factory that creates IDisposable objects, how to dispose them?

My application creates IDisposable objects that should be reused, so I create a factory that encapsulates the creation and reuse of those objects, code like this:
public class ServiceClientFactory
{
private static readonly object SyncRoot = new object();
private static readonly Dictionary<string, ServiceClient> Clients = new Dictionary<string, ServiceClient>(StringComparer.OrdinalIgnoreCase);
public static ServiceClient CreateServiceClient(string host)
{
lock(SyncRoot)
{
if (Clients.ContainsKey(host) == false)
{
Clients[host] = new ServiceClient(host);
}
return Clients[host];
}
}
}
public class QueryExecutor
{
private readonly ServiceClient serviceClient;
public QueryExecutor(string host)
{
this.serviceClient = ServiceClientFactory.CreateServiceClient(host);
}
public IDataReader ExecuteQuery(string query)
{
this.serviceClient.Query(query, ...);
}
}
What makes me scratch my head is, ServiceClient is IDisposable, I should dispose them explicitly sometime.
One way is implementing IDisposable in QueryExecutor and dispose ServiceClient when QueryExecutor is disposed, but in this way, (1) when disposing ServiceClient, also needs to notify ServiceClientFactory, (2) cannot reuse ServiceClient instance.
So I think it would be much easier to let ServiceClientFactory manage lifetime of all ServiceClient instances, if I go this way, what is the best practice here to dispose all IDisposable objects created by factory? Hook the AppDomain exit event and manually call Dispose() on every ServiceClient instance?
A couple of things to think about here...
Firstly, what you appear to be describing is some variation of the Flyweight pattern. You have an expensive object, ServiceClient, which you want to reuse, but you want to allow consumer objects to create and destroy at will without breaking the expensive object. Flyweight traditionally does this with reference-counting, which might be a bit old hat.
You'll need to make sure that consumers cannot dispose the ServiceClient directly, so you'll also need a lightweight Facade which intercepts the calls to ServiceClient.Dispose and chooses whether to dispose the real object or not. You should hide the real ServiceClient from consumers.
If all that is feasible, you could rewrite your approach as something like:
// this is the facade that you will work from, instead of ServiceClient
public interface IMyServiceClient : IDisposable
{
void Query(string query);
}
// This is your factory, reworked to provide flyweight instances
// of IMyServiceClient, instead of the real ServiceClient
public class ServiceClientFactory : IDisposable
{
// This is the concrete implementation of IMyServiceClient
// that the factory will create and you can pass around; it
// provides both the reference count and facade implementation
// and is nested inside the factory to indicate that consumers
// should not alter these (and cannot without reflecting on
// non-publics)
private class CachedServiceClient : IMyServiceClient
{
internal ServiceClient _realServiceClient;
internal int _referenceCount;
#region Facade wrapper methods around real ServiceClient ones
void IMyServiceClient.Query(string query)
{
_realServiceClient.Query(query);
}
#endregion
#region IDisposable for the client facade
private bool _isClientDisposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_isClientDisposed)
{
if (Interlocked.Decrement(ref _referenceCount) == 0)
{
// if there are no more references, we really
// dispose the real object
using (_realServiceClient) { /*NOOP*/ }
}
_isClientDisposed = true;
}
}
~CachedServiceClient() { Dispose(false); }
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
// The object cache; note that it is not static
private readonly ConcurrentDictionary<string, CachedServiceClient> _cache
= new ConcurrentDictionary<string, CachedServiceClient>();
// The method which allows consumers to create the client; note
// that it returns the facade interface, rather than the concrete
// class, so as to hide the implementation details
public IMyServiceClient CreateServiceClient(string host)
{
var cached = _cache.GetOrAdd(
host,
k => new CachedServiceClient()
);
if (Interlocked.Increment(ref cached._referenceCount) == 1)
{
cached._realServiceClient = new ServiceClient(host);
}
return cached;
}
#region IDisposable for the factory (will forcibly clean up all cached items)
private bool _isFactoryDisposed = false;
protected virtual void Dispose(bool disposing)
{
if (!_isFactoryDisposed)
{
Debug.WriteLine($"ServiceClientFactory #{GetHashCode()} disposing cache");
if (disposing)
{
foreach (var element in _cache)
{
element.Value._referenceCount = 0;
using (element.Value._realServiceClient) { }
}
}
_cache.Clear();
_isFactoryDisposed = true;
}
}
~ServiceClientFactory() { Dispose(false); }
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
// This is just an example `ServiceClient` which uses the default
// implementation of GetHashCode to "prove" that new objects aren't
// created unnecessarily; note it does not implement `IMyServiceClient`
public class ServiceClient : IDisposable
{
private readonly string _host;
public ServiceClient(string host)
{
_host = host;
Debug.WriteLine($"ServiceClient #{GetHashCode()} was created for {_host}");
}
public void Query(string query)
{
Debug.WriteLine($"ServiceClient #{GetHashCode()} asked '{query}' to {_host}");
}
public void Dispose()
{
Debug.WriteLine($"ServiceClient #{GetHashCode()} for {_host} was disposed");
GC.SuppressFinalize(this);
}
}
Secondly, in general, I'd remove the static clauses from the factory and make ServiceClientFactory : IDisposable. You'll see I've done that in my example above.
It may seem like you're just pushing the problem up the chain, but doing so allows you to make this decision on a case-by-case basis, per-something (application, session, request, unit test run -- whatever makes sense) and have the object that represents your something be responsible for the disposal.
If your application would benefit from a single-instance cache then expose a singleton instance as part of an AppContext class (for example) and call AppContext.DefaultServiceClientFactory.Dispose() in your clean-shutdown routine.
The emphasis here is on a clean shutdown. As others have stated, there is no guarantee that your Dispose method will ever actually be called (think power-cycling the machine, mid-run). As such, ideally, ServiceClient.Dispose would not have any tangible side-effects (i.e. beyond freeing resources that would be freed naturally if the process terminates or the machine power-cycles).
If ServiceClient.Dispose does have tangible side-effects, then you have identified a risk here, and you should clearly document how to recover your system from an "unclean" shutdown, in an accompanying user manual.
Thirdly, if both ServiceClient and QueryExecutor objects are intended to be reusable, then let the consumer be responsible for both the creation and disposal.
QueryExecutor only really has to be IDisposable in your sample because it can own a ServiceClient (which is also IDisposable). If QueryExecutor didn't actually create the ServiceClient, it wouldn't be responsible for destroying it.
Instead, have the constructor take a ServiceClient parameter (or, using my rewrite, an IMyServiceClient parameter) instead of a string, so the immediate consumer can be responsible for the lifetime of all objects:
using (var client = AppContext.DefaultServiceClientFactory.CreateServiceClient("localhost"))
{
var query = new QueryExecutor(client);
using (var reader = query.ExecuteReader("SELECT * FROM foo"))
{
//...
}
}
PS: Is there any need for consumers to actually directly access ServiceClient or are there any other objects which need a reference to it? If not, perhaps reduce the chain a little and move this stuff directly to QueryExecutor, i.e. using a QueryExecutorFactory to create flyweight QueryExector objects around cached ServiceClient instances, instead.
Static classes are tricky that way. The constructor for a static class is invoked when an instance member is first invoked. The class is destroyed if and when the application domain is destroyed. If the application terminates abruptly (aborts), there's no guarantee a constructor/finalizer would be called.
Your best bet here is to redesign the class to use a singleton pattern. There are ways to work around this issue, but they require strange, dark magic forces that may cost you your soul.
EDIT: As servy points out, a Singleton won't help here. A destructor is a finalizer, and you won't have any guarantee that it will be called (for a wide variety of reasons). If it were me, I'd simply refactor it to an instantiable class that implements IDisposable, and let the caller deal with calling Dispose. Not ideal, I know, but it's the only way to be sure.

Shared ownership of IDisposable objects in C#

Is there any classes in C# which provide shared ownership of IDisposable objects? Something like shared_ptr in c++? And if not, what are best practices here?
UPDATE
I'm writing a c++/cli wrapper over native lib. And I need release native resources (MAPI COM interfaces for example, so I need determenistic resource releasing).
Native part:
//Message.h
class Message
{ ... };
//MessageSet.h
class MessageSet
{
...
class iterator : public std::iterator<std::forward_iterator_tag, Message*>
{
...
public:
Message* operator*();
bool operator!=(const iterator& that);
iterator& operator++();
};
iterator begin();
iterator end();
};
Managed part (c++/cli):
public ref class Message
{
native::Message* inst;
public:
Message(native::Message* inst);
~Message();
!Message();
};
public ref class MessageSet : public IEnumerable<Message^>
{
native::MessageSet* inst;
public:
MessageSet(native::Message* inst);
~MessageSet();
!MessageSet();
virtual IEnumerator<Message^>^ GetEnumerator();
virtual System::Collections::IEnumerator^ EnumerableGetEnumerator() = System::Collections::IEnumerable::GetEnumerator;
};
When I use Message objects in TPL Dataflow (BroadcastBlock block i.e. there are many concurrent consumers) in C# I don't know when I should call Dispose() for these messages.
I think the best you could do is something like this:
public sealed class SharedDisposable<T> where T : IDisposable
{
public sealed class Reference : IDisposable
{
public Reference( SharedDisposable<T> owner )
{
mOwner = owner;
}
public void Dispose()
{
if( mIsDisposed ) return;
mIsDisposed = true;
mOwner.Release();
}
public T Value => mOwner.mValue;
private readonly SharedDisposable<T> mOwner;
private bool mIsDisposed;
}
public SharedDisposable( T value )
{
mValue = value;
}
public Reference Acquire()
{
lock( mLock )
{
if( mRefCount < 0 ) throw new ObjectDisposedException( typeof( T ).FullName );
mRefCount++;
return new Reference( this );
}
}
private void Release()
{
lock( mLock )
{
mRefCount--;
if( mRefCount <= 0 )
{
mValue.Dispose();
mRefCount = -1;
}
}
}
private readonly T mValue;
private readonly object mLock = new object();
private int mRefCount;
}
Basically this allows you to have one object (SharedDisposable<T>) manage the lifetime of the underlying disposable while providing a mechanism to distribute "shared" references to it.
One shortcoming here is that technically anyone could dispose the underlying value by accessing it through the shared reference Value property. You could address this by creating some sort of facade object that wraps the underlying disposable type but hides its Dispose method.
That would a NO.
Best way I found so far is quite clunky, using Dictionaries and WeakReferences. The Dictionary maps the object to it's refcount. WeakReference is used so you don't increase the ref count artificially.
You do not own IDisposable, you implement it, so .NET Garbage Collector will call overridden method in your class, notifying about a fact happened.
It's a different concept from shared_ptr, where destructor is guaranteed to be called once last ownership of a pointer is gone.
In general, in .NET, unless you are not using unsafe programming techniques, you do not own anything, .NET Garbage Collector owns it.
Even when you explicitly destroy an object, the memory allocated for it may not, and often will not, be reclaimed immediately, like once would expect from C++.
EDIT
If you have native resources and want release them in precise moment, you can achieve that by :
1) Implementing IDisposable with your .NET wrapper object
2) Inside Dispose() method of that wrapper write the code that releases native resources
3) In the code that consumes wrapper object, in the moment you would like to release native resources allocated by wrapper object, call explicitly Dispose() on it.
In this case Dispose() method is called, your code executes and releases native resources immediately.
EDIT (2)
After that is more clear what's the question about:
If you can not determine when Dispose() has to be called, I would stay with #Hans's comment: just relay on eventual (soon or later) GC call and avoid your own reference counter implementation (especially in multi threaded environment).
Do not invent the wheel, if that is a feasible in your situation.

Any risk to consider when implementing IDisposable?

I want to created a method that calls a repository class in a using() statement. That class is not currently disposable. Is there anything I should consider before making it implement IDisposable?
i.e.
using(var repo = new RespositoryClass() )
{
//do work
}
You should implement IDisposable if the class uses unmanaged resources, or initializes other members that implement it. Otherwise, don't use it if you don't need it.
Just because you use an IDisposable object inside a class does not mean that the class needs to implement IDisposable.
The example class below doesn't need to implement IDisposable.
class NotDisposable
{
public void someMethod()
{
using(SomethingDisposable resource = new SomethingDisposable ())
{...}
}
}
Here is an example of a class that would need to implement IDisposable.
class SomethingToDispose : IDisposable
{
private SomethingDisposable resource = new SomethingDisposable();
public void someMethod()
{
//code that uses resource
}
//code to dispose of "resource" in a Dispose method.
}
As you can see in this second example there isn't really anywhere for the class to put a using statement to dispose of the resource. Since it's storing the disposable object in a field, and it is the one responsible for disposing of it, the best way of ensuring that it gets disposed is to implement IDisposable.

Using statement in every function -> convert to class field with proper cleanup?

Basically I have a few functions that look like this:
class MyClass
{
void foo()
{
using (SomeHelper helper = CreateHelper())
{
// Do some stuff with the helper
}
}
void bar()
{
using (SomeHelper helper = CreateHelper())
{
// Do some stuff with the helper
}
}
}
Under the assumption I can use the same resource instead of a different one [instance] in every function is it ok practice in regard to cleanup and such to do this?:
class MyClass
{
SomeHelper helper = CreateHelper();
// ...foo and bar that now just use the class helper....
~MyClass()
{
helper.Dispose();
}
}
No, do not add a destructor (Finalizer).
You can reuse the resource but then your class has to implement IDisposable.
sealed class MyClass : IDisposable
{
SomeHelper helper = CreateHelper();
// ...foo and bar that now just use the class helper....
//~MyClass()
public void Dispose()
{
helper.Dispose();
}
}
And now you have to use MyClass instances in a using block. It self has become a managed resource .
A destructor is of no use, whenever a MyClass instance is being collected the associated helper object will also be in the same collection. But having a destructor still incurs considerable overhead.
The standard pattern for IDisposable uses a virtual void Dispose(bool disposing) method but when making the class sealed you can use the minimalistic implementation above.
In .NET you don't know when (or whether) finalizer is called at all.
Instead, explicitly indicate that your class is to be disposed of by implementing IDisposable:
(This is exactly what SomeHelper does)
class MyClass : IDisposable
{
readonly SomeHelper helper = CreateHelper();
// any method can use helper
public void Dispose()
{
helper.Dispose();
}
}
using(var myObj = new MyClass()) {
// at the end, myObj.Dispose() will trigger helper.Dispose()
}
I used readonly to ensure helper doesn't get re-assigned somewhere else in the class, but this really doesn't matter if you're careful.
You must be extra careful to never set it to null, or your Dispose will throw an exception. If the field is protected, you can check for nullity before calling Dispose on it so you know you're playing safe.
You can share such a resource during the lifetime of your object, in which case it is recommended that you implement IDisposable.
No, it is not. You don't know when the finalized will un. Also, if your resource is managed, it will be disposed of at some point without the finalized.
If you don't want to use using all the time, perhaps ou can use it once around many functions.
You don't need to override the finalizer in your object, which you have shown in your second code sample by ~MyClass().
You will need to implement the IDisposable pattern. You haven't been explicit in your question if you are using managed and unmanaged resources, but here's a quick sample for a managed resource. Stackoverflow has a myriad of examples on this. Reed Copsey also has a good series on it, and you can start here.
class MyClass : IDisposable
{
private bool _Disposed;
private SomeHelper _Helper;
protected virtual void Dispose()
{
this.Dispose(true);
}
public void Dispose(bool disposing)
{
if (_!Disposed && disposing)
{
if (_Helper != null)
_Helper.Dispose();
_Disposed = true;
}
}
}
The convention is that if your class owns an IDisposable object it should also implement IDisposable. So rather than implementing a finalizer your class should implement IDisposable and dipose of the helper there.
One problem with implementing the finalizer is that you have no control over when it's being called. The disposable pattern gives you a more deterministic way of cleaning up resources.

MEF ExportFactory<T> - How to properly dispose in a long-running application?

Basically, is there an easy way to dispose of the imports that are created by an ExportFactory<T>? The reason I ask is because the exports usually contain a reference to something that is still around, such as the EventAggregator. I don't want to run into the issue where I'm creating hundreds of these and leaving them laying around when they are not necessary.
I noticed that when I create the objects I get back a ExportLifetimeContext<T> which carries a Dispose with it. But, I don't want to pass back an ExportLifetimeContext to my ViewModels requesting copies of the ViewModel, hence I pass back the Value. (return Factory.Single(v => v.Metadata.Name.Equals(name)).CreateExport().Value;)
When you call Dispose on an ExportLifetimeContext<T> it will call dispose on any NonShared part involved in the creation of T. It won't dispose of any Shared components. This is a safe behaviour, because if the NonShared parts were instantiated purely to satisfy the imports for T, then they can safely be disposed as they won't be used by any other imports.
The only other way I think you could achieve it, would be to customise the Dispose method to chain the dispose call to any other member properties you import with, e.g.:
[Export(typeof(IFoo))]
public class Foo : IFoo, IDisposable
{
[Import]
public IBar Bar { get; set; }
public void Dispose()
{
var barDisposable = Bar as IDisposable;
if (barDisposable != null)
barDisposable.Dispose();
}
}
But as your type has no visibility of whether the imported instance of IBar is Shared or NonShared you run the risk of disposing of shared components.
I think hanging onto the instance of ExportedLifetimeContext<T> is the only safe way of achieving what you want.
Not sure if this helps, feels like unnecessary wrapping, but could you possibly:
public class ExportWrapper<T> : IDisposable
{
private readonly ExportLifetimeContext<T> context;
public ExportWrapper<T>(ExportLifetimeContext<T> context)
{
this.context = context;
}
public T Value
{
get { return context.Value; }
}
public void Dispose()
{
context.Dispose();
}
public static implicit operator T(ExportWrapper<T> wrapper)
{
return wrapper.Value;
}
public static implicit operator ExportWrapper<T>(ExportLifetimeContext<T> context)
{
return new ExportWrapper<T>(context);
}
}
Which you could possibly:
[Import(typeof(IBar))]
public ExportFactory<IBar> BarFactory { get; set; }
public void DoSomethingWithBar()
{
using (ExportWrapper<IBar> wrapper = BarFactory.CreateExport())
{
IBar value = wrapper;
// Do something with IBar;
// IBar and NonShared imports will be disposed of after this call finishes.
}
}
Feels a bit dirty...

Categories