如何确保我们只有一个实例,并以正确的方式处理

Dan*_*zyk 7 c# multithreading design-patterns idisposable

在我写的软件中,我将从外部设备(通过USB连接)读取一些数据.我给出的驱动程序(DLL文件)不是线程安全的,一次只能使用一个实例.我必须在C#中为这些驱动程序编写一个包装器.鉴于我有一个多线程应用程序,我想确保:

  1. 始终只使用一个实例(可能包装器是单件?).
  2. 它可以被处理以释放那里的驱动程序和资源(IDisposable?).

一次性单身人士我可以看出意见分歧,单身是否可以IDisposable.也许两者都有更好的解决方案?欢迎任何帮助.
现在我有一个IDisposable单身,如下所示:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 3

操作系统负责在进程终止时清理非托管资源。因此,如果您愿意从第一次使用资源到程序终止为止分配资源,我IDisposable根本不会实现。

话虽如此,为了可测试性,我很可能会避免公开暴露单例。考虑创建一个接口并使用依赖项注入在整个代码中注入相同的实例。我一般不喜欢单身人士。如果您打算使用其中一种,我建议您遵循我关于单例的文章中后面的模式之一。避免所有这些双重检查锁定废话:)