C#IAsyncResult异步回调函数的解释
问题:IAsyncResult ar 是如何通过ar.AsyncState强制转换成TCPClientState类型
答:实例中使用的方法如下
我给IAsyncResult ar传入了TCPClientState 类型的参数。简单来说:传入什么类型,转换时就需要什么类型。
TCPClientState state = (TCPClientState)ar.AsyncState;
IAsyncResult 传递的类型属于一个object 抽象类型
IAsyncResult 类型是非常严格的,有着非常明确的属性和方法。
但是其 AsyncState 属性不过就是一个最简单的 object 引用,把调用异步方法的你的代码所传送的对象参数给“读取”出来。
原因:.net framework的设计者不知道你要传递什么方法,而且那是2000年设计的功能,那时候也没有什么泛型,因此设计者给 IAsyncResult 类型设计了一个 object 类型的属性,让你用来传递参数。
代码方便理解:
IAsyncResult 部分代码:
#region 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll
#endregion using System.Runtime.InteropServices;
using System.Threading; namespace System
{
//
// 摘要:
// 表示异步操作的状态。
[ComVisible(true)]
public interface IAsyncResult
{
//
// 摘要:
// 获取用户定义的对象,它限定或包含关于异步操作的信息。
//
// 返回结果:
// 用户定义的对象,它限定或包含关于异步操作的信息。
object AsyncState { get; }
//
// 摘要:
// 获取用于等待异步操作完成的 System.Threading.WaitHandle。
//
// 返回结果:
// 用于等待异步操作完成的 System.Threading.WaitHandle。
WaitHandle AsyncWaitHandle { get; }
//
// 摘要:
// 获取一个值,该值指示异步操作是否同步完成。
//
// 返回结果:
// 如果异步操作同步完成,则为 true;否则为 false。
bool CompletedSynchronously { get; }
//
// 摘要:
// 获取一个值,该值指示异步操作是否已完成。
//
// 返回结果:
// 如果操作完成则为 true,否则为 false。
bool IsCompleted { get; }
}
}
TCPClientState 属性代码:
public class TCPClientState
{
/// <summary>
/// 与客户端相关的TcpClient
/// </summary>
public TcpClient TcpClient { get; private set; } /// <summary>
/// 获取缓冲区
/// </summary>
public byte[] Buffer { get; private set; } /// <summary>
/// 获取网络流
/// </summary>
public NetworkStream NetworkStream
{
get { return TcpClient.GetStream(); }
} public TCPClientState(TcpClient tcpClient, byte[] buffer)
{
if (tcpClient == null)
throw new ArgumentNullException("tcpClient");
if (buffer == null)
throw new ArgumentNullException("buffer"); this.TcpClient = tcpClient;
this.Buffer = buffer;
}
/// <summary>
/// 关闭
/// </summary>
public void Close()
{
//关闭数据的接受和发送
TcpClient.Close();
Buffer = null;
}
}
实例中的代码:
/// <summary>
/// 处理客户端连接的函数
/// </summary>
/// <param name="ar"></param>
private void HandleTcpClientAccepted(IAsyncResult ar)
{
if (IsRunning)
{
//TcpListener tcpListener = (TcpListener)ar.AsyncState; TcpClient client = _listener.EndAcceptTcpClient(ar);
byte[] buffer = new byte[client.ReceiveBufferSize]; TCPClientState state
= new TCPClientState(client, buffer);
lock (_clients)
{
_clients.Add(state);
RaiseClientConnected(state);
} NetworkStream stream = state.NetworkStream;
//开始异步读取数据
stream.BeginRead(state.Buffer, , state.Buffer.Length, HandleDataReceived, state); _listener.BeginAcceptTcpClient(
new AsyncCallback(HandleTcpClientAccepted), ar.AsyncState);
}
}
/// <summary>
/// 数据接受回调函数
/// </summary>
/// <param name="ar"></param>
private void HandleDataReceived(IAsyncResult ar)
{
if (IsRunning)
{
TCPClientState state = (TCPClientState)ar.AsyncState;
NetworkStream stream = state.NetworkStream; int recv = ;
try
{
recv = stream.EndRead(ar);
}
catch
{
recv = ;
} if (recv == )
{
// connection has been closed
lock (_clients)
{
_clients.Remove(state);
//触发客户端连接断开事件
RaiseClientDisconnected(state);
return;
}
} // received byte and trigger event notification
byte[] buff = new byte[recv];
Buffer.BlockCopy(state.Buffer, , buff, , recv);
//触发数据收到事件
RaiseDataReceived(state); // continue listening for tcp datagram packets
stream.BeginRead(state.Buffer, , state.Buffer.Length, HandleDataReceived, state);
}
}
C#IAsyncResult异步回调函数的解释的更多相关文章
- ArcGIS中使用异步回调函数查询图层Graphic
在我们的地图的操作中经常会有一些操作是需要通过画多边形或者画线来查找某一块区域内的特定的Graphics比如我们在做的交警的项目中通过框选来查找某一块区域中的摄像机,某一块区域中的警力.警情.警员等相 ...
- Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程
Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...
- WPF如何获得变量异步回调函数时产生的异步回调
有这样的问题,WPF当使用异步回调,需要使用产生的异步变量中的回调函数.数据库中查询诸如异步函数来获得一DataTable.怎样传递给回调函数呢? [方案一]使用全局变量 非常easy想到的是用全局变 ...
- C#--委托的同步,异步,回调函数
原文地址 同步调用 委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. using System; using System. ...
- 前端笔记之JavaScript(九)定时器&JSON&同步异步/回调函数&函数节流&call/apply
一.快捷位置和尺寸属性 DOM已经提供给我们计算后的样式,但是还是觉得不方便,因为计算后的样式属性值都是字符串类型. 不能直接参与运算. 所以DOM又提供了一些API:得到的就是number类型的数据 ...
- python 管道 事件(Event) 信号量 进程池(map/同步/异步)回调函数
####################总结######################## 管道:是进程间通信的第二种方式,但是不推荐使用,因为管道会导致数据不安全的情况出现 事件:当我运行主进程的 ...
- Cocos2d-x3.1回调函数具体解释
Cocos2d-x3.1回调函数的定义CCRef.h声明.源代码,例如,下面的: typedef void (Ref::*SEL_CallFunc)(); typedef void (Ref::*SE ...
- JS的异步回调函数
hi :)几日不见,趁着周末和父母在广州走走逛逛,游山玩水,放松身心,第一天上班就被一个问题难住了,不废话,以下是关于JS函数回调方面的知识,今天的查阅看的也是一知半解,摘录下来日后慢慢琢磨! js中 ...
- python异步回调函数的实现
#coding:utf-8 from socket import * import time #简单的服务器程序 监听用户连接,接收用户发来的信息,并返回反馈 def main(): HOST = & ...
随机推荐
- mysql-MHA 故障收集
在manager 主机上开启监控服务,启动不了 [root@manager ~]# managerStart [] [root@manager ~]# managerStatus app1 is st ...
- 新疆大学ACM-ICPC程序设计竞赛五月月赛(同步赛)- chess(威佐夫博奕)
---恢复内容开始--- 链接:https://www.nowcoder.com/acm/contest/116/G来源:牛客网 题意:一个棋盘,老王和小人下棋,棋子只能往下或者往左或者往左下走,小人 ...
- 树链剖分【p1505】[国家集训队]旅游
Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间 ...
- 拓扑排序【p1137】 旅行计划
Description 小明要去一个国家旅游.这个国家有\(N\)个城市,编号为\(1\)至\(N\),并且有\(M\)条道路连接着,小明准备从其中一个城市出发,并只往东走到城市\(i\)停止. 所以 ...
- 使用after伪类,配合IE的zoom或者overflow清除浮动
用after伪类实现,兼容多种浏览器:.clearfix:after {content:"."; display:block; height:0; clear:both; visi ...
- oracle exp CONSISTENT
exp相当于select,不会被其他操作锁定. 但是如果exp的时候指定了CONSISTENT = y,而数据库中又存在频繁修改,可能会导致exp的时候出现snapshot too old
- oracle case else end
--简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END --Case搜索函数 CASE WHEN sex = '1' ...
- [LOJ6281]数列分块入门 5
题目大意: 给你一个长度为$n(n\leq50000)$的序列$A(0\leq A_i<2^{31})$,支持进行以下两种操作: 1.将区间$[l,r]$中所有数开方: 2.询问区间$[l,r] ...
- 一次PHP面试经历
9月9号,去了一家朋友的公司参加面试,然后就被直接吊打了,问的许多问题居然是我压根没有关心过的,看起来只在高层搞框架不行啊,还是得自己造个轮子试试,下面回顾一下问到的问题和我自己找到的一些答案. fi ...
- iOS开发 Swift开发数独游戏(四) 游戏界面的界面与逻辑
一.游戏界面涉及到的功能点 1)数独格子的建模 (1)绘制数独格子要考虑到标记功能 所以要在每个格子内预先塞入9个标记数字,仅数独格子算下来就有9*9*9=729个格子且存在大量嵌套(这导致我在操作S ...