阅读串行通信 Visual Studios
Reading Serial Communication Visual Studios
我需要后台工作者的帮助。我正在尝试从串行端口读取数据(使用按钮可以正常工作)问题是我需要连续从串行端口读取数据,直到有人按下表单上的按钮(关闭按钮)停止读取。我试着通过添加一个循环来做到这一点,但它只是无限地 运行 并冻结了表格。我有以下代码,每当我按下按钮读取时,都会创建一个文件,但是当我按下关闭端口按钮时,它会显示
The I/O operation has been aborted because of either a thread exit or
an application request
关于如何解决这个问题有什么想法吗?
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
}
}
}
因为你有一个 do-while 结构,所以你在 END 评估条件!
因此,当您点击 Close
按钮并关闭 SerialPort 时,backgroundworker 仍然处于活动状态并且 运行 在后台尝试从 SerialPort
读取数据。它进入 do 隔间并尝试从关闭的端口读取,这就像 运行 又是一扇关闭的门 :) 这会导致异常。
你可以通过
解决
1) 将 while-evaluation 放在最上面并去掉 do
语句(使其成为一个简单的 while-loop)。这样 serialPort.ReadLine
将不再执行,因为您在点击关闭按钮时设置了 indicator = true;
。
可能在这种情况下,您应该将 indicator
的设置作为关闭端口前的第一行:
private void btnClose_Click(object sender, EventArgs e)
{
try
{
indicator = true;
serialPort1.Close();
或
2) 添加一个额外的 if 子句,确保仅在端口打开时读取!
if (serialPort1.IsOpen)
{
sw.WriteLine(serialPort1.ReadLine());
}
我需要后台工作者的帮助。我正在尝试从串行端口读取数据(使用按钮可以正常工作)问题是我需要连续从串行端口读取数据,直到有人按下表单上的按钮(关闭按钮)停止读取。我试着通过添加一个循环来做到这一点,但它只是无限地 运行 并冻结了表格。我有以下代码,每当我按下按钮读取时,都会创建一个文件,但是当我按下关闭端口按钮时,它会显示
The I/O operation has been aborted because of either a thread exit or an application request
关于如何解决这个问题有什么想法吗?
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
}
}
}
因为你有一个 do-while 结构,所以你在 END 评估条件!
因此,当您点击 Close
按钮并关闭 SerialPort 时,backgroundworker 仍然处于活动状态并且 运行 在后台尝试从 SerialPort
读取数据。它进入 do 隔间并尝试从关闭的端口读取,这就像 运行 又是一扇关闭的门 :) 这会导致异常。
你可以通过
解决1) 将 while-evaluation 放在最上面并去掉 do
语句(使其成为一个简单的 while-loop)。这样 serialPort.ReadLine
将不再执行,因为您在点击关闭按钮时设置了 indicator = true;
。
可能在这种情况下,您应该将 indicator
的设置作为关闭端口前的第一行:
private void btnClose_Click(object sender, EventArgs e)
{
try
{
indicator = true;
serialPort1.Close();
或
2) 添加一个额外的 if 子句,确保仅在端口打开时读取!
if (serialPort1.IsOpen)
{
sw.WriteLine(serialPort1.ReadLine());
}