我正在用 c# 编写一个应用程序,它利用 SerialPort
类与一些设备进行通信。现在我一直遇到的一个大问题是如何正确释放那里的资源,因为当您尝试使用已经被使用的串行端口时会立即出现异常。
由于通常 GC 应该负责大部分工作,所以我有点想不出还能尝试什么......
我主要尝试了 2 件事情(按照我的逻辑)应该可以完成工作。我使用基于 session 的通信,所以我在每次通信之前和之后调用一个 OpenPort
和一个 ClosePort
方法 - 所以应该关闭端口。我也尝试过将包含端口的对象设置为 null - 但我仍然一直得到 UnauthorizedAccessExceptions
- 尽管我 100% 确定 SerialPort.Close()
方法已被调用。
你们知道释放端口的更好方法吗,这样我就不会再收到异常了?
编辑: 感谢您的回答,但 Dispose() 的东西不起作用 - 我之前曾尝试过 - 也许我做错了什么所以这是我的代码的示例:
这实际上很像 Øyvind 的建议,虽然我只是添加了 IDisposable
- 但也不起作用:
所以这将是我的包装类:
class clsRS232 : IDisposable
{
public void clsRS232()
{
Serialport port = new Serialport("COM1",9600,Parity.none,8,Stopbits.one);
}
public void openPort()
{
port.Open();
}
public void sendfunc(string str)
{
port.Write(str);
}
public string readfunc()
{
port.ReadTo("\n");
}
public void Dispose()
{
port.Dispose();
}
}
现在每当我需要 rs232 通信时,我都会像这样调用一个新实例:
clsRS232 test = new clsRS232;
test.openport();
test.sendfunc("test");
test.Dispose();
但这并没有改变任何东西——我仍然得到很多 UnauthorizedAccessExceptions——如果另一个人是对的(SerialPort 类的 Dispose() 只包含 SerialPort.Close())——那么我想我还没有与我之前使用函数调用 close() 的方法相比,这并没有真正改变任何东西;
感谢您的回答 - 仍然希望找到解决方案:)
最佳答案
因为 SerialPort
实现了 IDisposable
,你应该这样写你的代码:
using( SerialPort port = new SerialPort( ... ) ){
//do what you need with the serial port here
}
这将确保在 using
block 结束时,串行端口被释放,如果在 using
block 内发生异常,它会被释放,因为using
block 与 try/finally block 完全相同,它关闭/处理 finally block 内的 SerialPort
。
编辑
根据 OP 的需要,SerialPort
应保持打开状态的时间长于方法的时间范围。
在那种情况下,我会将与串口有关的整个逻辑包装在它自己的类中。在类的构造函数中,打开串口,编写方法来完成你需要的操作。然后让此类实现 IDisposable
本身,并在您自己的 Dispose
方法中处理 SerialPort。
这将使您更好地控制必须打开和关闭/处理串口的位置,并将串口逻辑包装到适当的类中。
如果你想让端口在一段代码块不容易包含的时间段内保持打开状态,那么你将不得不在完成它时手动处理它,例如当使用它的函数关闭时或者任何触发程序中 com 端口释放的东西。
编辑 2
你当前的实现是这样的:
clsRS232 test = new clsRS232;
test.openport();
test.sendfunc("test");
test.Dispose();
这里的问题是,如果 sendfunc
以某种方式导致异常,它永远不会被释放。首先实现 IDisposable
的好处是,您可以将代码更改为如下所示:
using( clsRS232 test = new clsRS232 ){
test.openport();
test.sendfunc("test");
}
现在您可以保证 Dispose
将被调用用于您的 com 端口,而不管 using
block 中的任何异常。
关于c# - 正确释放串口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4365049/