【发布时间】:2014-02-27 13:58:14
【问题描述】:
在我正在编写的软件中,我将从外部设备(通过 USB 连接)读取一些数据。我得到的驱动程序(dll 文件)不是线程安全的,一次只能使用一个实例。我必须在 C# 中为这些驱动程序编写一个包装器。鉴于我有一个多线程应用程序,我想确保:
- 始终只使用一个实例(可能包装器是单例?)。
- 它可以被释放以释放那里的驱动程序和资源 (
IDisposable?)。
从Disposable Singleton 可以看出意见分歧,单例是否可以是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
}
}
【问题讨论】:
-
您真的需要处理它吗?你什么时候这样做?大概只是在应用程序结束时 - 如果该过程即将消失,为什么还要明确发布它? (它会自动发生。)您可能还想阅读 csharpindepth.com/Articles/General/Singleton.aspx 以使您的单例模式更简单。
-
如果我不调用适当的关闭函数(没有来自驱动程序源的文档),我不确定非托管代码(驱动程序)的行为方式
-
操作系统通常负责在进程终止时清理非托管资源。对于您希望在整个过程中保持开放的资源,这应该没问题。
-
那太好了,如果您将所有这些都作为答案,我可以将其标记为正确答案。再次感谢您的时间:)
-
@DanielGruszczyk,您可以使用 this 之类的东西来为非线程安全的非托管 DLL 实现线程亲和性。
标签: c# multithreading design-patterns idisposable