目录

第1章说明    2

1 为什么需要异步写数据?    2

2 异步写数据的代码    2

3 源代码    4

第1章说明

1 为什么需要异步写数据?

如下图所示,以波特率300打开一个串口。

图1

单击"同步发送"按钮,则数据未发送完之前写数据的函数不会返回。波特率300,每秒大概能发送25个字符,发送500个字符就需要20秒。这20秒之内,整个程序将处于假死状态。

单击"异步发送"按钮,就不会出现假死状态。

2 异步写数据的代码

异步写数据的代码如下:

private void btnWriteAsync_Click(object sender, EventArgs e)

{//异步写

byte[] byt = System.Text.Encoding.Default.GetBytes(txtSend.Text);

if(byt!=null && byt.Length > 0)

{

IntPtr hComm = GetCommHandle(m_sp);

UInt32 w = 0;

m_ov.hEvent = IntPtr.Zero;

m_ov.Internal = IntPtr.Zero;

m_ov.InternalHigh = IntPtr.Zero;

m_ov.Offset = 0;

m_ov.OffsetHigh = 0;

WriteFile(hComm, byt, (UInt32)byt.Length, ref w, ref m_ov);

}

}

要点为:

1)GetCommHandle函数获取.NET SerialPort对象的串口句柄hComm;

2)调用WriteFile函数,异步写数据。

以下是结构OVERLAPPED的声明、函数WriteFile的声明、函数GetCommHandle的实现:

[StructLayout(LayoutKind.Sequential,Pack=4)]

public struct OVERLAPPED

{

public IntPtr Internal;

public IntPtr InternalHigh;

public UInt32 Offset;

public UInt32 OffsetHigh;

public IntPtr hEvent;

}

[DllImport("kernel32.dll", SetLastError = true

, CallingConvention = CallingConvention.Winapi)]

private static extern UInt32 WriteFile(IntPtr hFile, byte[] lpBuffer

, UInt32 nNumberOfBytesToWrite

, ref UInt32 lpNumberOfBytesWritten

, ref OVERLAPPED lpOverlapped);

protected System.IO.Ports.SerialPort m_sp =

new System.IO.Ports.SerialPort();

protected OVERLAPPED m_ov;

static IntPtr GetCommHandle(System.IO.Ports.SerialPort sp)

{//获得串口句柄,供 Win32 API 使用

IntPtr hComm = IntPtr.Zero;

if (sp != null)

{

object stream = typeof(System.IO.Ports.SerialPort).GetField("internalSerialStream", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(sp);

var handle = (Microsoft.Win32.SafeHandles.SafeFileHandle)stream.GetType().GetField("_handle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(stream);

hComm = handle.DangerousGetHandle();

}

return hComm;

}

3 源代码

本文的代码已上传至git服务器:

https://github.com/hanford77/Exercise

https://git.oschina.net/hanford/Exercise

在目录 SerialPort\c# 目录内。

串行通讯之.NET SerialPort异步写数据的更多相关文章

  1. 串行通讯之.NET SerialPort

    第1章串行通讯之.NET SerialPort    2 1 枚举串口    2 2 打开/关闭串口    2 3 写数据    3 3.1 写二进制数据    3 3.2 写文本数据    4 4 ...

  2. 串行通讯之Qt

    目录 第1章 Qt 串行通讯    1 1.1 配置.pro文件    1 1.2 查询串口信息    1 1.3 配置.打开串口    3 1.4 setRequestToSend在Windows上 ...

  3. 【Arduino】使用C#实现Arduino与电脑进行串行通讯

    在给Arduino编程的时候,因为没有调试工具,经常要通过使用串口通讯的方式调用Serial.print和Serial.println输出Arduino运行过程中的相关信息,然后在电脑上用Arduin ...

  4. 串行通讯之UARTLoopback

    目录 第1章串行通讯之UARTLoopback    2 1 USB转串口    2 2 USB Accessory    2 3 连入手机    3 4 代码改进    4 5 打开串口    4 ...

  5. 基于51的串行通讯原理及协议详解(uart)

    串行与并行通讯方式并行:控制简单,传输速度快.线多,长距离成本较高且同时接受困难.串行:将数据字节分成一位一位的行驶在一条传输线上进行传输.如图:   同步与异步串行通讯方式同步串行通讯方式:同步通讯 ...

  6. COM口,串行通讯端口,RS-232接口 基础知识

    COM口即串行通讯端口. COM口的接口标准规范和总线标准规范是RS-232,有时候也叫做RS-232口.电脑上的com口多为9针,最大速率115200bps.通常用于连接鼠标(串口)及通讯设备(如连 ...

  7. STM32L476应用开发之三:串行通讯实验

    在我们的项目需求中,有两个串口应用需求,一个是与炭氢传感器的通讯,另一个是与显示屏的通讯.鉴于此,我们需要实验串行通讯. 1.硬件设计 串行通讯一个采用RS232接口,另一个直接采用TTL方式.我们在 ...

  8. STM32学习笔记——SPI串行通讯(向原子哥学习)

    一.SPI  简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在  EEPROM, FLASH,实时时钟,AD 转换器,还有数 ...

  9. 串行&并行&并发,同步&异步

    1. 串行&并行&并发 1.1 串行 这个非常好理解,字面意思,像串成一个串一样,顺序执行 上一个没执行完的话,后面的就必须无条件等待 一般情况就是一个线程里:任务一个接一个执行,类似 ...

随机推荐

  1. php 基础复习(2)GD库

    一,生成验证码: 1.生成一张图片: recource imagecreatetruecolor(int $width , int $height)  注意:提前输出图片的header信息,默认是黑色 ...

  2. ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 The Book List

    描述 The history of Peking University Library is as long as the history of Peking University. It was b ...

  3. P1533 可怜的狗狗

    http://www.luogu.org/problem/show?pid=1533 题目背景 小卡由于公务需要出差,将新家中的狗狗们托付给朋友嘉嘉,但是嘉嘉是一个很懒的人,他才没那么多时间帮小卡喂狗 ...

  4. 集合、ArrayList 集合。Stack集合。Queue集合。以及Hashtable集合

    arrayList 首先复制Colections加  : 创建arrayList ar =new arrayList(); //ArrayList al=new ArrayList();        ...

  5. Linux 性能监控、测试、优化工具

    Linux 平台上的性能工具有很多,眼花缭乱,长期的摸索和经验发现最好用的还是那些久经考验的.简单的小工具.系统性能专家 Brendan D. Gregg 在最近的 LinuxCon NA 2014 ...

  6. assert函数

    这个函数在<cassert>里面,通常用来调试程序. eg: int i=1: assert(i==1):/什么也不做 assert(i==2)://程序会异常退出

  7. Configuration对象

    Configuration对象 Hibernate的持久化操作离不开SessionFactory对象,使用该对象的openSession()方法可以打开Session对象.而SessionFactor ...

  8. about_Execution_Policies

    https://technet.microsoft.com/en-us/library/hh847748.aspx?f=255&MSPPError=-2147217396 在powershel ...

  9. SQL函数学习(十九):CAST()函数和CONVERT()函数

    19.CAST()函数和CONVERT()函数 CAST()函数可以将某种数据类型的表达式转化为另一种数据类型 CONVERT()函数 也 可以将指定的数据类型转换为另一种数据类型 19.1 CAST ...

  10. C# WPF MVVM 实战 – 5- 用绑定,通过 VM 设置 View 的控件焦点

    本文介绍在 MVVM 中,如何用 ViewModel 控制焦点. 这焦点设置个东西嘛,有些争论.就是到底要不要用 ViewModel 来控制视图的键盘输入焦点.这里不讨论,假设你就是要通过 VM,设置 ...