在重构一些代码时,我添加了一个"使用"这样的陈述:
using (SerialPort serialPort = new SerialPort())
{
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd);
serialPort.Close();
}
...但现在想知道我是否可以或应该取消对Close的调用。我估计是这样,但这只是一种精确的(风格点)还是一种名副其实的必需品?
答案 0 :(得分:4)
这实际上取决于类,如果作者按照建议实现了它 - 正确实现了IDisposable
,并且关闭除了调用Dispose()
之外什么都不做。在这种情况下,Close()
调用是多余的,可以在将类包装到using
块中时删除。
一般来说 - 在SerialPort
的特定情况下,他们这样做了,因此Close()
调用是多余的,可以删除。
答案 1 :(得分:4)
这实际上取决于实现IDisposable的特定类。对于一个实现IDisposable NOT的错误编写的类来说,完全可能无法正确释放资源并关闭连接。在SerialPort类的特定情况下,文档声明Close()调用Dispose()。我认为你应该在这种情况下把它放在一个使用块中,而不是手动调用Close()。
答案 2 :(得分:1)
按照里希特的说法:
提供确定性处置或能力的类型 关闭实施配置模式。处置模式定义 开发人员在定义类型时应遵循的约定 希望为该类型的用户提供显式清理。
由于SerialPort定义了一个打开和关闭它意味着它可以在它的生命周期内多次打开和关闭,这与它被处置(例如从未再次使用)相互排斥
但是回到你原来的问题,是的 - 在这种情况下它是多余的,反编译SerialPort对象显示dispose在调用时为你关闭了端口:
protected override void Dispose(bool disposing)
{
if (disposing && this.IsOpen)
{
this.internalSerialStream.Flush();
this.internalSerialStream.Close();
this.internalSerialStream = (SerialStream) null;
}
base.Dispose(disposing);
}
答案 3 :(得分:1)
如果在Dispose
出现异常情况,通常最好让Dispose
抛出异常而不是完全无声地完成(在任何特定情况下扼杀异常是否更好取决于一个例外是否已经悬而未决,而且还有一个机制,Dispose
可以知道何时该情况)。由于在Dispose
中没有良好的方法来处理异常,因此在Dispose
内完成任何可能出错的操作通常都是个好主意。{ 1}}将在调用Dispose
之前完成。
如果Dispose
是正常情况下唯一的清理方法,那么让它扼杀异常会带来很大的风险,可能会出现问题,但却未被发现。让一个类支持Close
和using
,并让客户在主线情况下调用Close
,将允许降低此类风险(如果异常待定,{{1将在没有Dispose
的情况下调用,因此清理上的任何异常都会被扼杀但代码会因为挂起的异常而知道某处出错了;如果在Close
之前没有发生异常,那么事实是它没有在Close
清理上下文中调用,这意味着它可以假设没有异常处于待处理状态,因此它可以安全地抛出它自己的一个。)
Dispose
和Dispose
的异常处理实践的一致性不高,但我建议原则上调用Close
。根据实现Close
和Dispose
的方式,在隐式Close
之前显式调用Close
可能会有所帮助,也可能没有帮助,但它应该是最无害的。考虑到它有用的可能性(如果不是在当前版本的课程中,也许在将来的版本中),我会建议它作为一般习惯。