目录

第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# 目录内。

最新文章

  1. C# 中的var关键字
  2. zend studio 做前端推荐安装的插件
  3. sql 2012 sequence 速记
  4. 十二、Java基础---------异常处理机制
  5. Python [Leetcode 344]Reverse String
  6. Unity3D之Mecanim动画系统学习笔记(三):Animation View
  7. Aggregation Models
  8. openMP的一点使用经验
  9. SqlBulkCopy使用心得 (大量数据导入)
  10. 【转】GATT Profile 简介
  11. VC++.Net CAD编程架构
  12. ural 1013. K-based Numbers. Version 3(动态规划)
  13. Mybatis,Spring,SpringMVC框架面试题
  14. R学习笔记 第五篇:字符串操作
  15. [THUWC2017] 在美妙的数学王国畅游
  16. mysql的基本查询(等于,不等于,between...and...,)
  17. 试试SQLServer 2014的内存优化表
  18. QQ通信机制(转)
  19. 2016年蓝桥杯省赛A组c++第4题(算法填空)
  20. Jmeter工具

热门文章

  1. FlashFXP命令行
  2. fildder学习
  3. 双4G LTE
  4. 二SERVLET(2)
  5. Quartz实用二三事
  6. Java反序列化漏洞通用利用分析
  7. Shell概述
  8. C++ Redis mset 二进制数据接口封装方案
  9. 函数对象适配器之ptr_fun的使用示例
  10. git学习笔记07-冲突了怎么办-那就解决冲突呗