任何人都可以指向一个使用.net 4.5异步API(异步,等待,任务<>,ReadAsync等)进行串行通信的工作示例吗?我试图改编现有的事件驱动的串行示例,并获取各种可怕的行为 - “其他应用程序使用的端口”错误,VS2013调试器抛出异常并锁定 - 通常需要PC重新启动从中恢复。使用.net 4.5中的Async API的串口通信代码示例?
编辑
我已经写了从无到有我自己的样品。这是一个写入输出窗口的简单的Winforms项目。表单上的三个按钮 - 打开端口,关闭端口和读取数据。 ReadDataAsync方法调用SerialPort.BaseStream.ReadAsync。
截至目前,它会从端口读取数据,但我遇到了问题,使其强大。例如,如果我拔掉串行电缆,打开端口,然后单击读取数据两次,我将得到一个System.IO.IOException(我期待的),但是我的应用程序停止响应。更糟糕的是,当我尝试停止我的程序时,VS2013抛出一个“停止调试进行中”对话框,它永远不会完成,我甚至无法从任务管理器中杀死VS.每次发生这种情况时都必须重启我的电脑。
不好。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private SerialPort _serialPort;
public Form1()
{
InitializeComponent();
}
private void openPortbutton_Click(object sender, EventArgs e)
{
try
{
if (_serialPort == null)
_serialPort = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
if (!_serialPort.IsOpen)
_serialPort.Open();
Console.Write("Open...");
}
catch(Exception ex)
{
ClosePort();
MessageBox.Show(ex.ToString());
}
}
private void closePortButton_Click(object sender, EventArgs e)
{
ClosePort();
}
private async void ReadDataButton_Click(object sender, EventArgs e)
{
try
{
await ReadDataAsync();
}
catch (Exception ex)
{
ClosePort();
MessageBox.Show(ex.ToString(), "ReadDataButton_Click");
}
}
private async Task ReadDataAsync()
{
byte[] buffer = new byte[4096];
Task<int> readStringTask = _serialPort.BaseStream.ReadAsync(buffer, 0, 100);
if (!readStringTask.IsCompleted)
Console.WriteLine("Waiting...");
int bytesRead = await readStringTask;
string data = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine(data);
}
private void ClosePort()
{
if (_serialPort == null) return;
if (_serialPort.IsOpen)
_serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
Console.WriteLine("Close");
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
ClosePort();
}
}
}
SerialPort没有异步方法,因为它本质上是异步性质的,它使用线程来处理通信,因此只需使用它的方法和事件就足够了。发布你的代码来检查它,看看有什么不对。还添加错误。 – Gusman
其他SO帖子暗示我可以使用像SerialPort.BaseStream.ReadAsync等东西,我打电话给这个方法。你是说这不起作用吗? –
嗯,从来没有使用SerialPort的底层流,但我怀疑它不会正常工作(也许我错了),我已经使用了多年的SerialPort并使用Write和Read函数和DataReceived事件应该已经足够并且已经异步。 – Gusman