How to make sure that we have only one instance and it is located correctly

In the software that I write, I read some data from an external device (connected via USB). The drivers that were provided to me (the dll file) are not thread safe, and only one instance can be used at a time. I have to write a shell for these drivers in C #. Given that I have a multi-threaded application, I would like to make sure that:

  • Only one instance is always used (maybe the wrapper is a single?)
  • Is it possible to remove drivers and resources there (IDisposable?)

From Disposable Singleton, I see that opinions are divided whether Singleton can be IDisposable or not. Maybe there is a better solution for both? Any help is appreciated.
At the moment, I have an IDisposable singleton, as shown 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 } } 
+7
multithreading c # design-patterns idisposable
source share
2 answers

The operating system is responsible for cleaning up unmanaged resources when the process ends. Therefore, if you are satisfied that the resources will be allocated from the moment you first use the resource until the program ends, I would not implement IDisposable at all.

Having said that, for verification we could well have avoided exposing the singleton publicly. Consider creating an interface and using dependency injection to inject the same code instance. I donโ€™t like loners at all. If you intend to use it, I would suggest the following one of the later templates in my article on singletones . Avoid all these double check delays :)

+3
source share

I would not recommend using a one-time static singleton, but instead should have a method that returns an IDisposable (or a list of objects) that encapsulates the currently connected device (s). Many USB drivers, which are mostly limited to single-threaded operation, have a single situation where multithreading is allowed: any stream may require that the driver instance be disconnected, as a result of which any pending or future operations are interrupted as soon as possible. Shutdown can be inactive, and if you want to close and restart a device that is โ€œstuckโ€, you need to be prepared for the fact that attempts to reopen can fail and / or block if they were released before completion.

Despite the fact that the OS will try to clean up any USB device drivers that the program can use when exiting the system, such cleaning does not always work, and I would avoid relying on it. It would be better to get rid of things that you can when you know that they are no longer needed. From the point of abstraction, if you use the singleton method, which identifies the connected device (s), if any, there is no problem deleting the device (s) identified by it. Once the devices are located, they will no longer appear in the list until something is done to reconnect.

0
source share

All Articles