C# · 12月 23, 2021

c# – 正确释放串行端口

我正在用c#编写一个应用程序,它利用SerialPort类与少数设备进行通信.现在我遇到的最大问题是如何在那里正确释放资源,因为在尝试使用已经使用的串口时会立即出现异常.

由于通常GC应该处理大部分工作,我有点想法还有什么可以尝试…

主要是我尝试了两件事(按照我的逻辑)应该做的工作.我使用基于会话的通信,因此我在每次通信之前和之后调用OpenPort和ClosePort方法 – 因此应该关闭端口.此外我尝试将包含端口的对象设置为null – 但我仍然一直得到UnauthorizedAccessExceptions – 尽管我百分之百确定已经调用了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块与try / finally块完全相同,因此关闭/在finally块中部署SerialPort.

编辑

根据OP的需求,SerialPort应保持打开的时间长于方法的时间范围.

在这种情况下,我将包装与其自己的类中的串行端口有关的整个逻辑.在类的构造函数中,打开串行端口,并编写方法来执行所需的操作.然后让这个类实现IDisposable本身,并将SerialPort配置在你自己的Dispose方法中.

这将使您更好地控制打开和关闭/部署串行端口的位置,并将串行端口逻辑包装到适当的类中.

如果你想让端口打开一段不容易被代码块包含的时间,那么当你完成它时你必须手动处理它,例如当使用它的函数被关闭或任何触发器时在程序中释放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”);}

现在可以保证,无论使用块内是否有任何异常,都将为您的COM端口调用Dispose.