[英].NET SerialPort DataReceived event not firing
我有一个WPF测试应用程序,用于评估基于事件的串行端口通信(与轮询串行端口)。 问题是DataReceived事件似乎根本没有触发。
我有一个非常基本的WPF表单,其中包含用于用户输入的TextBox,用于输出的TextBlock以及用于将输入写入串行端口的按钮。
这是代码:
public partial class Window1 : Window
{
SerialPort port;
public Window1()
{
InitializeComponent();
port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
port.DataReceived +=
new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Debug.Print("receiving!");
string data = port.ReadExisting();
Debug.Print(data);
outputText.Text = data;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Debug.Print("sending: " + inputText.Text);
port.WriteLine(inputText.Text);
}
}
现在,以下是复杂因素:
我正在处理的笔记本电脑没有串口,因此我使用一个名为Virtual Serial Port Emulator的软件来设置COM2。 VSPE过去曾经令人钦佩地工作,并且不清楚为什么它只会出现.NET的SerialPort类故障,但我提到它以防万一。
当我点击表单上的按钮发送数据时,我的超级终端窗口(连接在COM2上)显示数据正在通过。 是的,当我想测试我的表单读取端口的能力时,我断开Hyperterminal的连接。
在尝试连接事件之前,我尝试打开端口。 没变。
我已经阅读了另一篇文章,其中有人遇到了类似的问题。 在这种情况下,这些信息都没有帮助我。
编辑:
这是控制台版本(从http://mark.michaelis.net/Blog/TheBasicsOfSystemIOPortsSerialPort.aspx修改):
class Program
{
static SerialPort port;
static void Main(string[] args)
{
port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
port.DataReceived +=
new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
string text;
do
{
text = Console.ReadLine();
port.Write(text + "\r\n");
}
while (text.ToLower() != "q");
}
public static void port_DataReceived(object sender,
SerialDataReceivedEventArgs args)
{
string text = port.ReadExisting();
Console.WriteLine("received: " + text);
}
}
这应该消除任何担心这是一个线程问题(我认为)。 这也不起作用。 同样,Hyperterminal报告通过端口发送的数据,但控制台应用程序似乎没有触发DataReceived事件。
编辑#2:
我意识到我有两个独立的应用程序,应该从串口发送和接收,所以我决定尝试同时运行它们...
如果我输入控制台应用程序,WPF应用程序DataReceived事件将触发,并出现预期的线程错误(我知道如何处理)。
如果我输入WPF应用程序,控制台应用程序DataReceived事件将触发,并且它会回显数据。
我猜这个问题出在我使用VSPE软件的某个地方,该软件设置为将一个串口视为输入和输出。 通过SerialPort类的一些奇怪,串行端口的一个实例不能同时是发送方和接收方。 无论如何,我认为它已经解决了。
port.DtrEnable = true;
这解决了它,我没有启用DataTransmitReady标志,因此没有收到任何数据。
我不能肯定地说,但可能存在线程问题。 WPF以不同的方式处理线程,我相信虚拟端口的轮询是异步的。 您是否尝试使用Windows窗体或控制台应用程序来证明它可以工作?
我使用完全相同的设置,它现在完美地工作,但必须解决很多问题才能到达那里。
这就是为什么我的初始声明如下:
comControl = new SerialPort();
//This is important - determine your min nb of bytes at which you will fire your event, mine is 9
comControl.ReceivedBytesThreshold = 9;
//register the event handlers
comControl.DataReceived += new SerialDataReceivedEventHandler(OnReceive);
comControl.PinChanged += new SerialPinChangedEventHandler(OnPinChanged);
我分开了开放端口和关闭端口方法,因为我经常检查com端口是否已经关闭。
public bool OpenPort()
{
try
{
//must keep it open to maintain connection (CTS)
if (!comControl.IsOpen)
{
comControl.Open();
comControl.RtsEnable = true;
}
}
catch (Exception e)
{
//error handling here
}
}
最后,验证您的Virtual Com Port驱动程序是否已正确安装并且您使用的是正确的端口,我的适配器的即插即用是不够的。 如果要创建一种允许您在运行时选择可用端口的控件,以下命令将为您提供可用端口:
System.IO.Ports.SerialPort.GetPortNames()
从Form中运行这样的驱动程序时也有类似的问题,尽管没有VSPE只是一个普通的SP。 相信这是一个STA模型问题,因为它将其包含在足够固定的控制台应用程序中。
我也用VSPE! 它运行得非常好..我遇到了同样的问题,我修复它的方法是在VSPE中使两个COM端口成为PAIR而不是仅创建两个虚拟COM端口
我最近遇到了一个同样奇怪的问题,但只在某些机器上。 正如Dave Swersky所说,这可能是一个线程问题,特别是如果你在.NET 4.0或更高版本下运行。
在.NET 4.0中,事件处理程序在ThreadPool线程上触发,在某些情况下,在此之前可能会有很长的延迟。 (在我的代码中,一直在.NET 2.0下完美运行,一旦我们升级到.NET 4.5就会出现问题。事件处理程序通常会比预期的更晚触发,有时它不会被触发所有!)
调用具有更大值的ThreadPool.SetMinThreads(...)
完成线程使得问题尽快消失。 在我们的应用程序的上下文中, ThreadPool.SetMinThreads(2, 4)
就足够了。 在观察到问题的机器上,默认值(通过调用ThreadPool.SetMinThreads
获得)都是2。
我只能推测问题确实存在于虚拟串口仿真器程序中。 这并不是说该软件存在问题:到目前为止,VSPE对我来说效果很好。 但是我的代码和我如何设置VSPE连接器之间存在一些冲突。
两天前我遇到了同样的问题,这是一个非常令人头痛的问题,因为我今天需要提供应用程序。 所以..经过太多googleashion后我认为问题是另一回事,而不是我的代码。
我的解决方案是卸载McAfee防病毒以及与此相关的所有事情。 当我看到McAfee的日志时,它有关于停止线程的记录,我假设SerialDataReceivedEventHandler()
在一个线程中运行。
我希望这个解决方案适合你。 问候。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.