问题: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);
}
}

最新文章

  1. iOS - UIButton设置文字标题下划线以及下划线颜色
  2. 远程重装centos6
  3. SQL Server 2008 通用分页存储过程
  4. jquery遍历
  5. 进阶学习js中的执行上下文
  6. JavaScript获取Select下拉框Option的Value和Text值的方法
  7. B - 确定比赛名次
  8. HttpUrlConnection get和post简单实现(疑惑解决)
  9. iOS开发工具——统计Crash的工具Crashlytics
  10. 初学HTML5的一点理解
  11. JAVA – 虚函数、抽象函数、抽象类、接口
  12. 【Luogu3444】ORK-Ploughing(贪心)
  13. Samba原理和配置
  14. 大数据批量导入,解决办法,实践从定时从 sqlserver 批量同步数据到 mySql
  15. DotNetCore跨平台~认识环境和环境变量
  16. SQL-55 分页查询employees表,每5行一页,返回第2页的数据
  17. MySql:SELECT 语句(一)基本查询
  18. 项目上有红色感叹号, 一般就是依赖包有问题, remove依赖,重新加载,maven的也行可认删除,自己也会得新加载
  19. 教你用Cordova打包Vue项目
  20. HTTP 头和 PHP header() 函数

热门文章

  1. 你不一定知道的、并没有什么卵用的一些python库
  2. 【linux高级程序设计】(第九章)进程间通信-管道 1
  3. centos6源码编译安装lnmp环境
  4. DB2—alter追加/删除/重置column操作
  5. Netty源码学习(六)ChannelPipeline
  6. ZOJ 3940 Modulo Query (2016年浙江省赛E题,区间折叠 + map运用)
  7. Python的程序结构[4] -&gt; 函数/Function[0] -&gt; 函数与方法的区别
  8. 【bzoj4152】【The Captain】最短路(堆优化)(浅尝ACM-B)
  9. [POI2013]Tower Defense Game
  10. Flash3D学习计划(二)&mdash;&mdash;理解世界,取景,投影变换,并理解投影坐标系