如何确保我们只有一个实例,并以正确的方式进行处理
在我写的软件中,我将从外部设备(通过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?