[英]Reading Serial Communication Visual Studios
I need some help with Background worker. 我需要背景工作者的帮助。 I am trying to read data from a serial port (works fine with a button) the problem is that I need to continuously read from the serial port, until someone presses a button (Close button) on the form to stop reading.
我正在尝试从串行端口读取数据(可以通过按钮正常工作),问题是我需要不断从串行端口读取数据,直到有人按下表单上的按钮(关闭按钮)以停止读取为止。 I tried doing this by adding a loop, but it just ran infinitely and froze up the form.
我尝试通过添加一个循环来执行此操作,但是它无限运行并冻结了表单。 I have the following code, whenever I press the button to read, a file is created, but when I press the close port button,it says
我有以下代码,每当我按下按钮进行读取时,都会创建一个文件,但是当我按下关闭端口按钮时,它会说
The I/O operation has been aborted because of either a thread exit or an application request
由于线程退出或应用程序请求,I / O操作已中止
Any ideas on how to fix this? 有想法该怎么解决这个吗?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
namespace SerialCommunication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
GetAvaliablePortNames();
}
bool indicator;
StreamWriter sw = new StreamWriter(@"C:\Users\slahiri\Desktop\Data\jumbo.txt");
void GetAvaliablePortNames()
{
string[] Ports = SerialPort.GetPortNames();
cmbPort.Items.AddRange(Ports);
}
private void btnOpen_Click(object sender, EventArgs e)
{
try
{
if (cmbPort.Text == "" || cmbBaud.Text == "")
{
MessageBox.Show("Please select the Port and Baud Rates");
}
else
{
serialPort1.PortName = cmbPort.Text;
serialPort1.BaudRate = Convert.ToInt32(cmbBaud.Text);
serialPort1.Open();
progressBar1.Value = 100;
groupBox2.Enabled = true;
btnRead.Enabled = true;
btnOpen.Enabled = false;
btnClose.Enabled = true;
}
}
catch (UnauthorizedAccessException)
{
txtRead.Text = "Unauthorized Acess";
}
}
private void btnClose_Click(object sender, EventArgs e)
{
serialPort1.Close();
progressBar1.Value = 0;
btnClose.Enabled = false;
btnRead.Enabled = false;
btnOpen.Enabled = true;
indicator = true;
}
private void btnRead_Click(object sender, EventArgs e)
{
if (btnRead.Text == "Read")
{
btnRead.Text = "Stop and Close Port";
progressBar1.Maximum = 1000;
progressBar1.Value = 0;
backgroundWorker1.RunWorkerAsync(progressBar1.Maximum);
indicator = false;
}
else
{
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.CancelAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
int max = (int)e.Argument;
int n = 0;
indicator = false;
do
{
//write to serial writer
sw.WriteLine(serialPort1.ReadLine());
if (backgroundWorker1.CancellationPending)
{
sw.Flush();
sw.Close();
e.Cancel = true;
break;
}
// backgroundWorker1.ReportProgress(n++);
}
while (indicator ==false);
}
catch (TimeoutException)
{
//Close Serial Writer & Messagebox
//txtRead.Text = "Time Out!";
MessageBox.Show("TimeOut Exception");
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//progressBar1.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
btnRead.Text = "Read";
//close serial writer
}
}
} }
Since you have a do-while construct you evaluate the condition at the END! 由于您具有do-while构造,因此可以在END评估条件! So when you hit the
Close
button and close the SerialPort the backgroundworker is still active and running in the background trying to read from the SerialPort
. 因此,当您单击“
Close
按钮并关闭SerialPort时,backgroundworker仍处于活动状态并在后台运行,试图从SerialPort
读取数据。 It enters the do compartment and tries to read from a closed port, which is like running agains a closed door :) this leads to the exception. 它进入do隔间并尝试从关闭的端口读取数据,就像再次在关闭的门上运行:)那样会导致异常。
You could solve it by 你可以通过解决
1) putting the while-evaluation on top and get rid of the do
statement (making it a simple while-loop). 1)将while评估放在最前面并摆脱
do
语句(使其成为一个简单的while循环)。 This way the serialPort.ReadLine
will not be executed anymore, because you set indicator = true;
这样,不再执行
serialPort.ReadLine
,因为您设置了indicator = true;
when hitting the close button. 点击关闭按钮时。
May be in this case you should put the setting of indicator
as the first line before closing the port: 在这种情况下,可能应该在关闭端口之前将
indicator
的设置作为第一行:
private void btnClose_Click(object sender, EventArgs e)
{
try
{
indicator = true;
serialPort1.Close();
Or 要么
2) put an extra if clause that makes sure to read only if the port is open! 2)放置一个额外的if子句,以确保仅在端口打开时才能读取!
if (serialPort1.IsOpen)
{
sw.WriteLine(serialPort1.ReadLine());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.