问题描述
我正在编写一个 Windows 服务,用于与串行磁条阅读器和中继板(访问控制系统)进行通信.
I'm writing a Windows Service for communication with a Serial Mag-stripe reader and a relay board (access control system).
在另一个程序通过打开与我的服务相同的串行端口中断"进程后,我遇到了代码停止工作(我得到 IOExceptions)的问题.
I run into problems where the code stops working (i get IOExceptions) after another program has "interrupted" the process by opening the same serial port as my service.
部分代码如下:
public partial class Service : ServiceBase
{
Thread threadDoorOpener;
public Service()
{
threadDoorOpener = new Thread(DoorOpener);
}
public void DoorOpener()
{
while (true)
{
SerialPort serialPort = new SerialPort();
Thread.Sleep(1000);
string[] ports = SerialPort.GetPortNames();
serialPort.PortName = "COM1";
serialPort.BaudRate = 9600;
serialPort.DataBits = 8;
serialPort.StopBits = StopBits.One;
serialPort.Parity = Parity.None;
if (serialPort.IsOpen) serialPort.Close();
serialPort.Open();
serialPort.DtrEnable = true;
Thread.Sleep(1000);
serialPort.Close();
}
}
public void DoStart()
{
threadDoorOpener.Start();
}
public void DoStop()
{
threadDoorOpener.Abort();
}
protected override void OnStart(string[] args)
{
DoStart();
}
protected override void OnStop()
{
DoStop();
}
}
我的示例程序成功启动了工作线程,并且 DTR 的打开/关闭和提升导致我的磁条阅读器通电(等待 1 秒)、关闭(等待 1 秒)等等.
My sample program successfully starts the work-thread, and the opening/closing and raising of DTR causes my Mag-stripe reader to power up (wait 1sec), shut down (wait 1 sec) and so on.
如果我启动超级终端并连接到同一个 COM 端口,超级终端会告诉我该端口当前正在使用中.如果我在超级终端中反复按 ENTER,尝试重新打开重试几次后会成功的端口.
If I launch HyperTerminal and connects to the same COM port, HyperTerminal tells me the port is currently in use. If i repeatedly press ENTER in HyperTerminal, to try to reopen the port it will succeed after a few retries.
这会在我的工作线程中导致 IOExceptions,这是预期的.但是,即使我关闭了超级终端,我的工作线程中仍然会收到相同的 IOException.唯一的治疗方法实际上是重新启动计算机.
This has the effect of causing IOExceptions in my work-thread, which is expected. However, even if I close down HyperTerminal, i still get the same IOException in my work-thread. The only cure is actually to restart the computer.
其他程序(未使用 .NET 库进行端口访问)此时似乎可以正常工作.
Other programs (which is not using .NET libraries for port-access) seem to work normally at this point.
关于造成这种情况的任何想法?
Any ideas as to what is causing this?
推荐答案
@thomask
是的,Hyperterminal 实际上在 SetCommState 的 DCB 中启用了 fAbortOnError,这解释了 SerialPort 对象抛出的大多数 IOExceptions.一些 PC/手持设备还具有默认打开错误中止标志的 UART - 因此串行端口的 init 例程必须清除它(微软忽略了这样做).我最近写了一篇长文来更详细地解释这一点(参见 this 如果你有兴趣).
Yes, Hyperterminal does in fact enable fAbortOnError in SetCommState's DCB, which explains for most of the IOExceptions thrown by the SerialPort object. Some PCs / handhelds also have UARTs that have the abort on error flag turned on by default - so it's imperative that a serial port's init routine clears it (which Microsoft neglected to do). I wrote a long article recently to explain this in greater detail (see this if you're interested).
这篇关于如何使用 .NET/C# 进行健壮的 SerialPort 编程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!