C# 串行端口类的问题

C# 串行端口类的问题,c#,serial-port,C#,Serial Port,我有一个串行端口类,看起来像这样: public static class OldHaspCommunication { private static SerialPort m_port; private static string m_portName; private static bool m_isOpen = false; private static int m_baudRate; private static Parity m_parit

我有一个串行端口类,看起来像这样:

 public static class OldHaspCommunication
 {
    private static SerialPort m_port;
    private static string m_portName;
    private static bool m_isOpen = false;

    private static int m_baudRate;
    private static Parity m_parity;
    private static int m_dataBits;
    private static StopBits m_stopBits;
    private static bool m_xonxoff;
    private static bool m_dtr;
    private static bool m_rts;

    // ................................

    // Open port.
    public static void OpenPort(string portName,
                                int baudRate,
                                Parity parity,
                                int dataBits,
                                StopBits stopBits,
                                bool dtr,
                                bool rts,
                                bool xonxoff = false)
    {

        // Create new Serial Port object
        m_port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);

        // .........................................
        // Set class member variables.

        m_portName = portName;
        m_baudRate = baudRate;
        m_parity = parity;
        m_dataBits = dataBits;
        m_stopBits = stopBits;
        m_xonxoff = xonxoff;
        m_dtr = dtr;
        m_rts = rts;

        // ............................................
        // Initialize some port object properties

        // XOnXOff - parameter
        if (xonxoff)
            m_port.Handshake = Handshake.XOnXOff;

        // Set DTR/RTS 
        m_port.DtrEnable = dtr;
        m_port.RtsEnable = rts;

        // Set
        m_port.ReadTimeout = 500;
        m_port.WriteTimeout = 500;

        // ..............................................
        // Some final steps.

        // Open the port for communications
        m_port.Open();

        // If we get this far, mark port as opened.
        m_isOpen = true;
    }

    /// <summary>
    /// Just makes sure to read the specified number of bytes from the serial port.
    /// Typical reads may return fewer bytes then told to read. This method is used
    /// to avoid this problem.
    /// Based on a similar function from Jon Skeet: http://jonskeet.uk/csharp/readbinary.html
    /// </summary>
    /// <param name="data"> [OUT] Data read should be stored here</param>
    /// <param name="length"> [IN] How much data to read exactly </param>
    /// <param name="count"> [IN] Some kind of retry count parameter.</param>
    private static void ReadAll(byte[] data, uint length, int retryCount)
    {

        // Check data length parameter.
        if (length > data.Length)
        {
            throw new Exception("Wrong data length in ReadAll");
        }

        int offset = 0;
        int i = 0;
        int remaining = checked((int)length); // NOTE: Will throw OverflowException if length > Int32.MaxValue due to checked keyword.

        // Start reading.
        while (remaining > 0)
        {
            // Just a retry count check
            if (i >= retryCount)
            {
                throw new Exception("Exceeded retry count parameter during reading in ReadAll");
            }

            // Read Certain amount of bytes
            int read = m_port.Read(data, offset, remaining);

            // Was there error?
            if (read <= 0)
            {
                throw new EndOfStreamException(String.Format("ReadAll(OldHaspCommunication) - End of data reached with {0} bytes left to read", remaining));
            }

            // Advance offset, and decrease remaining count.
            remaining -= read;
            offset += read;

            i++;

        }


    }

    /// <summary>
    /// Write specified number of bytes to the serial port
    /// </summary>
    /// <param name="data"> [IN] Buffer from which to write data</param>
    /// <param name="length"> [IN] How many bytes to write</param>
    private static void WriteAll(byte[] data, uint length)
    {           
        // TODO: Maybe we should add a retry count as in C++

        int len = checked((int)length); // NOTE: Will throw OverflowException if length > Int32.MaxValue due to checked keyword.

        // We can't write more data to serial port than available in the array.
        if (len > data.Length)
        {
            throw new Exception("Wrong data length in WriteAll");
        }

        // Do the write.
        m_port.Write(data, 0, len);
    }





    /// <summary>
    /// Close the serial port.
    /// NOTE: Don't forget to call this one.
    /// </summary>
    public static void ClosePort()
    {
        if (m_isOpen)
        {
            Reset(); // Calls our custom Reset function.
            m_port.Close(); // Close port
            m_isOpen = false; // Mark this object as closed.
        }
    }

    // ...
    private static void Reset()
    {
        m_port.DiscardInBuffer();
        m_port.DiscardOutBuffer();
    }


}
Query
函数(上面列出的)也来自HASP类-为了清晰起见,我删除了它们,它们只是以不同的方式调用
read/write
方法,在某些情况下可能调用
Reset

你能解释一下发生了什么问题以及原因吗?(
Reset
函数被一个
Query
函数调用)。 这一定与我拔下搭扣有关吧? 但为什么会有这样的例外

如何修改我的类,以便如果有人拔下搭扣然后将其插入,对搭扣的调用仍然成功?


请注意,最初我的设计是在应用程序中调用一次
OpenPort
。在应用程序中调用
ClosePort

虽然捕获异常代价很高,但我认为您需要捕获它,如果我没有弄错的话,您使用的HASP是USB到COM emulator

  • 您可以使用WMI检测HASP(USB)连接——或
  • 在ReadAll/WriteAll/Reset上断开连接期间捕获异常--或
  • 创建线程以监视异常,并重新启动线程以重试连接

将在一段时间内尝试提供伪代码。

请先尝试理解问题。事实上,我检查了,当我拔下HASP时,SerialPort类的isOpen属性仍然返回true,只是协议报告的签名计算失败。我必须与HASPif对话,如果我不删除HASP,它工作正常;这只是我连接到COM端口的正常搭扣
2016-02-10 13:01:14 - [LOG_ERROR] [THREAD ID: 11] General Exception: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
   at ProcessingLibrary.OldHaspCommunication.Reset() in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\HASP\OldHaspCommunication.cs:line 270
   at ProcessingLibrary.OldHaspCommunication.QueryParam(Byte[] in_buffer, UInt32 length, Byte command, Byte[] out_buffer, UInt32 szBuf, Byte& ret_code, Int32 l_entry, Int32 l_loop, Boolean quick_ser_no) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\HASP\OldHaspCommunication.cs:line 303
   at ProcessingLibrary.OldHaspCommunication.Query(Byte[] in_buffer, UInt32 length, Byte command, Byte[] out_buffer, UInt32 szBuff, Byte& retcode) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\HASP\OldHaspCommunication.cs:line 277
   at ProcessingLibrary.OldHaspCommunication.QueryCmd8(Byte[] in_buffer, Byte command, Byte[] out_buffer) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\HASP\OldHaspCommunication.cs:line 286
   at ProcessingLibrary.CryptographyUtilities.SetSessionKey() in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\Security\CryptographyUtilities.cs:line 94
   at ProcessingLibrary.CryptographyUtilities.OldHASPSign(Byte[] buffer, UInt32 size, Byte[] outbuffer, Boolean session) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\Security\CryptographyUtilities.cs:line 137
   at ProcessingLibrary.UpdateTerminalInfoMethods.TestConnection(ProcessingErrorInfo& errorInfo, String terminalID, UInt32 STAN) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\Processing Functions\UpdateTerminalInfoMethods.cs:line 70