我有一个类似于此的串口类:
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();
}
}
它似乎工作正常,但在这种情况下我遇到了问题。 当我的设备HASP插入计算机时,一切都很顺利。 然后我拔掉了搭扣并继续使用该类,但我收到的错误是我正在错误地计算数据(签名错误,我使用写/读调用计算)。
然后我再次插入我的HASP并得到了这样的异常(带有堆栈跟踪):
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
Query
函数(上面列出的)也来自HASP类 - 为了清楚起见,我删除了它们,它们只是以不同方式调用read/write
方法,在某些情况下可能Reset
。
您能否解释一下发生了什么问题?为什么? (Reset
函数被Query
函数之一调用了。
这必须与我拔掉HASP的事实有关?
但是为什么会出现这种异常呢?
如何修改我的课程,以便如果有人拔出HASP然后插入,那么对HASP的调用是否仍然成功?
请注意,我的设计最初是在申请时拨打OpenPort
。并且在申请时也要拨打ClosePort
一次。
答案 0 :(得分:0)
虽然捕获异常代价很高,但我认为你需要抓住它,如果我没有弄错,你使用的HASP是USB-to-COM模拟器?
将尝试在一段时间内提供伪代码。