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

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

  • 总是只使用一个实例(可能是一个单例包装?)。
  • 它可以被处置以释放那里的驱动程序和资源( 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
        }
    }
    

    当进程终止时,操作系统负责清理非托管资源。 因此,如果您对从首次使用该资源的点开始分配资源感到高兴,直到程序终止,我根本不会实现IDisposable

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


    我不会推荐拥有一个直接使用的静态单例,而是有一个方法返回一个封装当前连接设备的IDisposable对象(或对象列表)。 大多数限于单线程操作的USB驱动程序都有一个允许多线程的情况:任何线程都可能请求驱动程序实例关闭,导致任何未决或将来的操作在第一时间中止。 关机可能不会立即进行,如果想关闭并重新启动已“卡住”的设备,则必须做好准备,以便重新打开尝试可能失败和/或在关机完成前发出时阻止。

    尽管操作系统会尝试清理程序在退出时可能使用的任何USB设备驱动程序,但这种清理并不总是奏效,我会避免依赖它。 当你知道他们不再需要时,处理你可以做的事情会更好。 从抽象的角度来看,如果使用单一方法来识别连接的设备(如果有的话),处置由此识别的设备是没有问题的。 一旦设备被丢弃,它们将不再出现在列表中,直到完成重新建立连接的操作。

    链接地址: http://www.djcxy.com/p/19291.html

    上一篇: How to make sure we have only one instance, and it is disposed in a correct way

    下一篇: how can I access Picasso' s cached image to make a share intent?