如果我不将其标记为静态,串行端口将无法工作

Serial port doesn't work if i will not mark it as static

我正在打开一个串口通信,如下例:

public class ModemSerialPort
{
    public ModemSerialPort(string serialPort)
    {

        if (!string.IsNullOrWhiteSpace(serialPort))
        {
            var mySerialPort = new SerialPort(serialPort);
            mySerialPort.BaudRate = 115200;
            mySerialPort.Parity = Parity.None;
            mySerialPort.StopBits = StopBits.One;
            mySerialPort.DataBits = 8;
            mySerialPort.Handshake = Handshake.None;

            mySerialPort.Open();

            mySerialPort.DataReceived += MySerialPort_DataReceived;
        }
    }

在我的表单中

private void Main_Load(object sender, EventArgs e)
{
 var modemInit = new ModemSerialPort("COM1");
}

上面的例子不成立

仅当我将 SerialPort 标记为静态时。

public class ModemSerialPort
{

 private static SerialPort mySerialPort;

 public ModemSerialPort(string serialPort)
 {

    if (!string.IsNullOrWhiteSpace(serialPort))
    {
       mySerialPort = new SerialPort(serialPort);
       ////
     }
  }

为什么会这样? gc 收集器会清除我的 class 吗?加载事件结束后?

此外,如果我在 class 中使用 public 静态方法而不是默认构造函数,有什么不同吗?示例

public class ModemSerialPort
{
  public static void ModemInit(string serialPort)
  {

  }
}

并在 OnLoad 方法内部

ModemSerialPort.ModemInit("COM1"); 

所以,首先,我可以看出您对 static 的含义和使用方法有点困惑。为此,我建议您阅读微软文档中的这篇文章:Static Classes and Static Class Methods

您可以说,class 对您的对象来说是某种 "template" 或 "skeleton"。这意味着,如果您的 class Person 具有属性 NameAge,您可以随时创建新对象 new Person() 并根据需要设置属性。之后,您将拥有多个具有不同属性 NameAge 的不同对象。但是如果你说这个 class 是静态的:public static class Person,那就意味着你不能从它创建对象并且整个程序中只有一个实例。

与您的问题相同。但这取决于您的应用程序的目的。如果您只想打开一个串行端口而不使用任何其他端口。比我建议使用这样的东西:

public static class ModemSerialPort
{
  public static SerialPort OpenedSerialPort;

  public static void ModemInit(string serialPort)
  {
    ...
    OpenedSerialPort = new SerialPort()
    ...
  }
}

你将只有一个这个静态实例 class 并且你可以像 ModemSerialPort.ModemInit("COM3") 这样调用......并且在初始化之后,你可以在 [=21= 下使用打开的串口].

如果要打开多个串口,不能使用静态class或静态方法

public class ModemSerialPort
{
  public SerialPort OpenedSerialPort;

  public void ModemInit(string serialPort)
  {
    ...
    OpenedSerialPort = new SerialPort()
    ...
  }
}

但是在这里,您需要先创建一个对象 var modem = new ModemSerialPort() 然后初始化它 modem.ModemInit("COM3") 然后您将在 modem.OpenedSerialPort 下打开串口......但是!

在你的 Main_Load 方法中,你必须将 modem 变量存储在某个地方,否则在 Main_Load 方法完成后,所有对不再使用的变量的引用都将丢失,GC 将最终处理这个对象。

我希望这会有所帮助...