private void ReceiveThread() { byte[] lpBuffer = new byte[1]; bool flag = true; AutoResetEvent event2 = new AutoResetEvent(false); Win32Com.OVERLAPPED structure = new Win32Com.OVERLAPPED(); uint num2 = 0; IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(structure)); IntPtr ptr2 = Marshal.AllocHGlobal(Marshal.SizeOf(num2)); structure.Offset = 0; structure.OffsetHigh = 0; structure.hEvent = event2.Handle; Marshal.StructureToPtr(structure, ptr, true); try { while (true) { if (!Win32Com.SetCommMask(this.hPort, 0x1fd)) { throw new CommPortException("IO Error [001]"); } Marshal.WriteInt32(ptr2, 0); if (flag) { this.startEvent.Set(); flag = false; } if (!Win32Com.WaitCommEvent(this.hPort, ptr2, ptr)) { if (Marshal.GetLastWin32Error() != 0x3e5L) { throw new CommPortException("IO Error [002]"); } event2.WaitOne(); } num2 = (uint)Marshal.ReadInt32(ptr2); if ((num2 & 0x80) != 0) { uint num3; if (!Win32Com.ClearCommError(this.hPort, out num3, IntPtr.Zero)) { throw new CommPortException("IO Error [003]"); } int num4 = 0; StringBuilder builder = new StringBuilder("UART Error: ", 40); if ((num3 & 8) != 0) { builder = builder.Append("Framing,"); num4++; } if ((num3 & 0x400) != 0) { builder = builder.Append("IO,"); num4++; } if ((num3 & 2) != 0) { builder = builder.Append("Overrun,"); num4++; } if ((num3 & 1) != 0) { builder = builder.Append("Receive Cverflow,"); num4++; } if ((num3 & 4) != 0) { builder = builder.Append("Parity,"); num4++; } if ((num3 & 0x100) != 0) { builder = builder.Append("Transmit Overflow,"); num4++; } if (num4 > 0) { builder.Length--; throw new CommPortException(builder.ToString()); } if (num3 != 0x10) { throw new CommPortException("IO Error [003]"); } num2 |= 0x40; } if ((num2 & 1) != 0) { uint num; do { num = 0; if (!Win32Com.ReadFile(this.hPort, lpBuffer, 1, out num, ptr)) { int num5 = Marshal.GetLastWin32Error(); throw new CommPortException("IO Error [004]"); } if (num == 1) { this.OnRxChar(lpBuffer[0]);//这个就是触发事件 } }while (num > 0); } if ((num2 & 4) != 0) { lock (this.empty) { this.empty[0] = true; } this.OnTxDone(); } if ((num2 & 0x40) != 0) { this.OnBreak(); } uint val = 0; if ((num2 & 8) != 0) { val |= 0x10; } if ((num2 & 0x10) != 0) { val |= 0x20; } if ((num2 & 0x20) != 0) { val |= 0x80; } if ((num2 & 0x100) != 0) { val |= 0x40; } if (val != 0) { uint num7; if (!Win32Com.GetCommModemStatus(this.hPort, out num7)) { throw new CommPortException("IO Error [005]"); } this.OnStatusChange(new ModemStatus(val), new ModemStatus(num7)); } } } catch (Exception exception) { Win32Com.CancelIo(this.hPort); if (ptr2 != IntPtr.Zero) { Marshal.FreeHGlobal(ptr2); } if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } if (!(exception is ThreadAbortException)) { this.rxException = exception; this.OnRxException(exception); } } }
public bool Open() { Win32Com.DCB lpDCB = new Win32Com.DCB(); Win32Com.COMMTIMEOUTS lpCommTimeouts = new Win32Com.COMMTIMEOUTS(); Win32Com.OVERLAPPED structure = new Win32Com.OVERLAPPED(); if (!this.online) { CommBaseSettings settings = this.CommSettings(); this.hPort = Win32Com.CreateFile(settings.port, 0xc0000000, 0, IntPtr.Zero, 3, 0x40000000, IntPtr.Zero); if (this.hPort == ((IntPtr)(-1))) { if (Marshal.GetLastWin32Error() == 5L) { return(false); } this.hPort = Win32Com.CreateFile(this.AltName(settings.port), 0xc0000000, 0, IntPtr.Zero, 3, 0x40000000, IntPtr.Zero); if (this.hPort == ((IntPtr)(-1))) { if (Marshal.GetLastWin32Error() != 5L) { throw new CommPortException("Port Open Failure"); } return(false); } } this.online = true; lpCommTimeouts.ReadIntervalTimeout = uint.MaxValue; lpCommTimeouts.ReadTotalTimeoutConstant = 0; lpCommTimeouts.ReadTotalTimeoutMultiplier = 0; if (settings.sendTimeoutMultiplier == 0) { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { lpCommTimeouts.WriteTotalTimeoutMultiplier = 0; } else { lpCommTimeouts.WriteTotalTimeoutMultiplier = 0x2710; } } else { lpCommTimeouts.WriteTotalTimeoutMultiplier = settings.sendTimeoutMultiplier; } lpCommTimeouts.WriteTotalTimeoutConstant = settings.sendTimeoutConstant; lpDCB.init((settings.parity == Parity.odd) || (settings.parity == Parity.even), settings.txFlowCTS, settings.txFlowDSR, (int)settings.useDTR, settings.rxGateDSR, !settings.txWhenRxXoff, settings.txFlowX, settings.rxFlowX, (int)settings.useRTS); lpDCB.BaudRate = settings.baudRate; lpDCB.ByteSize = (byte)settings.dataBits; lpDCB.Parity = (byte)settings.parity; lpDCB.StopBits = (byte)settings.stopBits; lpDCB.XoffChar = (byte)settings.XoffChar; lpDCB.XonChar = (byte)settings.XonChar; if (((settings.rxQueue != 0) || (settings.txQueue != 0)) && !Win32Com.SetupComm(this.hPort, (uint)settings.rxQueue, (uint)settings.txQueue)) { this.ThrowException("Bad queue settings"); } if ((settings.rxLowWater == 0) || (settings.rxHighWater == 0)) { Win32Com.COMMPROP commprop; if (!Win32Com.GetCommProperties(this.hPort, out commprop)) { commprop.dwCurrentRxQueue = 0; } if (commprop.dwCurrentRxQueue > 0) { lpDCB.XoffLim = lpDCB.XonLim = (short)(commprop.dwCurrentRxQueue / 10); } else { lpDCB.XoffLim = (short)(lpDCB.XonLim = 8); } } else { lpDCB.XoffLim = (short)settings.rxHighWater; lpDCB.XonLim = (short)settings.rxLowWater; } if (!Win32Com.SetCommState(this.hPort, ref lpDCB)) { this.ThrowException("Bad com settings"); } if (!Win32Com.SetCommTimeouts(this.hPort, ref lpCommTimeouts)) { this.ThrowException("Bad timeout settings"); } this.stateBRK = 0; if (settings.useDTR == HSOutput.none) { this.stateDTR = 0; } if (settings.useDTR == HSOutput.online) { this.stateDTR = 1; } if (settings.useRTS == HSOutput.none) { this.stateRTS = 0; } if (settings.useRTS == HSOutput.online) { this.stateRTS = 1; } this.checkSends = settings.checkAllSends; structure.Offset = 0; structure.OffsetHigh = 0; if (this.checkSends) { structure.hEvent = this.writeEvent.Handle; } else { structure.hEvent = IntPtr.Zero; } this.ptrUWO = Marshal.AllocHGlobal(Marshal.SizeOf(structure)); Marshal.StructureToPtr(structure, this.ptrUWO, true); this.writeCount = 0; this.empty[0] = true; this.dataQueued = false; this.rxException = null; this.rxExceptionReported = false; this.rxThread = new Thread(new ThreadStart(this.ReceiveThread));//打开串口的同时也打开了接收线程 this.rxThread.Name = "CommBaseRx"; this.rxThread.Priority = ThreadPriority.AboveNormal; this.rxThread.Start(); this.startEvent.WaitOne(500, false); this.auto = false; if (this.AfterOpen()) { this.auto = settings.autoReopen; return(true); } this.Close(); } return(false); }