.NET 中的 SerialPort 是非托管资源吗?我的包裹类正确吗?
我在串行端口类上有适配器模式(包装器)。我应该实现 IDisposable 模式并在其中调用 _wrappedSerialPort.Dispose() 吗?有我的班级,对吗?
public class SerialPortAdapter : ISerialPortAdapter
{
private bool _disposed;
public event SerialDataReceivedEventHandler DataReceived;
private readonly SerialPort _wrappedSerialPort;
public SerialPort WrappedSerialPort
{
get { return _wrappedSerialPort; }
}
public string PortName
{
get { return _wrappedSerialPort.PortName; }
set { _wrappedSerialPort.PortName = value; }
}
public BaudRate BaudRate
{
get { return (BaudRate)Enum.ToObject(typeof(BaudRate), _wrappedSerialPort.BaudRate); }
set { _wrappedSerialPort.BaudRate = (int)value; }
}
public bool IsOpen
{
get { return WrappedSerialPort.IsOpen; }
}
public SerialPortAdapter(SerialPort serialPort)
{
_wrappedSerialPort = serialPort;
_wrappedSerialPort.DataReceived += SerialPortDataReceived;
}
public void OpenPort()
{
if (!_disposed)
{
if (!WrappedSerialPort.IsOpen)
{
WrappedSerialPort.Open();
}
}
}
public void ClosePort()
{
if (!_disposed)
{
if (WrappedSerialPort.IsOpen)
{
WrappedSerialPort.Close();
}
}
}
public void WriteLine(string request)
{
...
}
public void Write(byte[] request)
{
....
}
public byte[] Read()
{
....
}
public string ReadLine()
{
...
}
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (DataReceived != null)
{
DataReceived(this, e);
}
}
#region IDisposable Members
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose managed resources.
}
// Dispose unmanaged resources.
ClosePort();
WrappedSerialPort.DataReceived -= SerialPortDataReceived;
_wrappedSerialPort.Dispose();
_disposed = true;
}
}
~SerialPortAdapter()
{
Dispose(false);
}
#endregion
}
编辑:是否有必要调用此函数,或者仅调用 _wrappedSerialPort.Dispose(); 就足够了?
ClosePort();
WrappedSerialPort.DataReceived -= SerialPortDataReceived;
_wrappedSerialPort.Dispose();
I have adapter pattern (wrapper) over serial port class. Should I implement IDisposable pattern and call _wrappedSerialPort.Dispose() in it? There is my class, is it correct?
public class SerialPortAdapter : ISerialPortAdapter
{
private bool _disposed;
public event SerialDataReceivedEventHandler DataReceived;
private readonly SerialPort _wrappedSerialPort;
public SerialPort WrappedSerialPort
{
get { return _wrappedSerialPort; }
}
public string PortName
{
get { return _wrappedSerialPort.PortName; }
set { _wrappedSerialPort.PortName = value; }
}
public BaudRate BaudRate
{
get { return (BaudRate)Enum.ToObject(typeof(BaudRate), _wrappedSerialPort.BaudRate); }
set { _wrappedSerialPort.BaudRate = (int)value; }
}
public bool IsOpen
{
get { return WrappedSerialPort.IsOpen; }
}
public SerialPortAdapter(SerialPort serialPort)
{
_wrappedSerialPort = serialPort;
_wrappedSerialPort.DataReceived += SerialPortDataReceived;
}
public void OpenPort()
{
if (!_disposed)
{
if (!WrappedSerialPort.IsOpen)
{
WrappedSerialPort.Open();
}
}
}
public void ClosePort()
{
if (!_disposed)
{
if (WrappedSerialPort.IsOpen)
{
WrappedSerialPort.Close();
}
}
}
public void WriteLine(string request)
{
...
}
public void Write(byte[] request)
{
....
}
public byte[] Read()
{
....
}
public string ReadLine()
{
...
}
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (DataReceived != null)
{
DataReceived(this, e);
}
}
#region IDisposable Members
public virtual void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose managed resources.
}
// Dispose unmanaged resources.
ClosePort();
WrappedSerialPort.DataReceived -= SerialPortDataReceived;
_wrappedSerialPort.Dispose();
_disposed = true;
}
}
~SerialPortAdapter()
{
Dispose(false);
}
#endregion
}
Edit: Is it necessary to call this, or is enough to call only _wrappedSerialPort.Dispose();?
ClosePort();
WrappedSerialPort.DataReceived -= SerialPortDataReceived;
_wrappedSerialPort.Dispose();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Henk Holterman 的答案是正确的:SerialPort 是一个托管资源,它本身拥有一个非托管资源,因此实现了
IDisposable
。由于您的包装器拥有 SerialPort,因此它间接拥有 SerialPort 的非托管资源,因此必须实现 IDisposable。您的实现是错误的,只有在
diswriting
为 true 时才应处置拥有的 SerialPort 实例,因为它是托管资源。它应该按如下方式实现:
此外,正如 Henk Holterman 指出的那样,如果您直接拥有非托管资源,则只需要一个析构函数,但这里的情况并非如此,并且您可以通过获取来简化 IDisposable 实现摆脱析构函数。
Henk Holterman's answer is correct: SerialPort is a managed resource, which itself owns an unmanaged resource and hence implements
IDisposable
.Since your wrapper owns a SerialPort, it indirectly owns SerialPort's unmanaged resource and hence must implement IDisposable. Your implementation is wrong, the owned SerialPort instance should only be disposed if
disposing
is true, since it is a managed resource.It should be implemented as follows:
Also, as Henk Holterman points out, you only need a destructor if you directly own unmanaged resources, which is not the case here, and you can simplify the IDisposable implementation by getting rid of the destructor.
SerialPort 本身是非托管资源的所有者,这就是它实现完整一次性模式的原因。
在您的类中,
_wrappedSerialPort
是一个托管资源。我的定义:托管资源是间接非托管资源。您的班级不需要需要完整的模式。您可以而且应该省略析构函数(或终结器),
~SerialPortAdapter ()
,然后您可以跳过 SupressFinalize。最好保留其余部分,但您会发现很容易进一步缩短代码(因为
void Dispose(bool)
永远不会用false
调用>)。The SerialPort itself is the owner of an unmanaged resource and that is why it implements the full Disposable pattern.
In your class, the
_wrappedSerialPort
is a managed resource. My definition: a managed resource is an indirect unmanaged resource.Your class does not need the full pattern. You could and should omit the destructor (or finalizer),
~SerialPortAdapter ()
and following that you can skip the SupressFinalize.It would be best to leave the rest, but you will see it would be easy to shorten the code a lot more (because
void Dispose(bool)
will never be called withfalse
).是的,在这种情况下,您实现
Dispose
方法是正确的。确保将IDisposable
添加到您的类声明中。这使得可以使用非常方便的using
构造,如下所示:在包装的串行端口上调用 Dispose 应该足够了,因为这将关闭端口。根据 MS 文档,
Close
将在内部调用Dispose
。不过,通过显式调用Close
来明确您的意图并没有什么坏处。像您一样,从活动中取消注册是一个很好的做法。
http://msdn.microsoft.com/en -us/library/system.io.ports.serialport.close.aspx
Yes, you are correct in implementing a
Dispose
method in this case. Make sure to addIDisposable
to your class declaration. This makes it possible to use the very handyusing
construct, like this:Calling Dispose on the wrapped serial port ought to be enough, since this will close the port. According to MS documentation,
Close
will callDispose
internally. No harm in being clear in your intentions by explicitly callingClose
, though.Unregistering from the event, like you are doing, is good practice.
http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.close.aspx
是的,串行罐是一个非托管报告。或者您是否见过物理硬件的垃圾收集器? ;)
这由实现 IDisposable 的访问类显示 - 这意味着您托管长期引用的类也必须实现 IDISPOSABLE。
Yes, the serial pot is an unmanaged report. Or did you ever see a garbage collector for the PHYSICAL HARDWARE? ;)
This is shown by the class for access implementing IDisposable - which means your class hosting a lon term refernce pertty much HAS TO IMPLEMENT IDISPOSABLE, TOO.