In the software I am writing I will read some data from an external device (connected via USB). The drivers I have been given (dll file) are not thread safe and only one instance can be used at a time. I have to write a wrapper to these drivers in C#. Given that I have a multi-threaded application, I would like to make sure that:
IDisposable
?).From Disposable Singleton I can see that the opinions are divided, can a singleton be IDisposable
or not. Maybe there is a better solution to both? Any help welcome.
For now I have an IDisposable
singleton, like below:
using System;
using System.Runtime.InteropServices;
namespace Philips.Research.Myotrace.DataReading.Devices
{
class MyDevice: IDisposable
{
private static volatile MyDeviceInstance;
private static object SyncRoot = new Object();
private bool disposed = false;
private MyDevice()
{
//initialize unmanaged resources here (call LoadLibrary, Initialize, Start etc)
}
public MyDevice GetInstance()
{
if (Instance == null)
{
lock (SyncRoot)
{
if (Instance == null)
{
Instance = new MyDevice();
}
}
}
return Instance;
}
public void Dispose()
{
this.Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
//dispose of unmanaged resources here (call Stop and Close from reflection code
Instance = null;
}
this.disposed = true;
}
}
[DllImport("devicedrivers.dll")]
private static extern bool Initialize();
[DllImport("devicedrivers.dll")]
private static extern bool LoadLibrary();
[DllImport("devicedrivers.dll")]
private static extern bool Start();
[DllImport("devicedrivers.dll")]
private static extern bool Stop();
[DllImport("devicedrivers.dll")]
private static extern bool Close();
//and few more
}
}
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.
Implement a finalizer to free resources when Dispose is not called. By default, the garbage collector automatically calls an object's finalizer before reclaiming its memory.
The operating system is responsible for cleaning up unmanaged resources when the process terminates. So if you're happy for the resources to be allocated from the point at which you first use the resource until the program termination, I wouldn't implement IDisposable
at all.
Having said that, for the sake of testability I would quite possibly avoid exposing the singleton publicly. Consider creating an interface and using dependency injection to inject the same instance throughout your code. I generally dislike singletons. If you're going to use one though, I'd suggest following one of the later patterns in my article on singletons. Avoid all this double-checked locking nonsense :)
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