首页 > Web开发 > 详细

串行通讯之.NET SerialPort异步写数据

时间:2016-12-05 22:29:34      阅读:332      评论:0      收藏:0      [点我收藏+]

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);

}

}

要点为:

1GetCommHandle函数获取.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异步写数据

原文:http://www.cnblogs.com/hanford/p/6135470.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!