采用同步方式封装异步操作(AutoResetEvent)

在C/S模式程序开发中需要实现一个函数,比如:

 

 

ContractedBlock.gif ExpandedBlockStart.gif Code
string GetUserName(int id)
{
}

 

它的实现需求是通过 TCP 向 Server 端请求指定用户 Id 所对应的用户名。

通常实现 socket 通讯的步骤是,我们先构造一个请求包,包含请求的指令和参数。

然后把它 Send() 出去。

Server 端接收到这个请求,查询符合条件的信息,并向客户端发送请求结果。

客户端的接收线程接收到 Server 端发来的信息,对其进行解析,并执行相应的操作。

这样的话,我势必需要在 GetUserName 函数中实现请求,并通过另一个函数去获取查询结果。

因为对于网络通讯来说,发起和获取可以说是异步的,这对于 GetUserName 函数的使用者来说显然太麻烦了。

那么怎么才能实现 string username=GetUserName(10); 这样的调用呢?

 

考虑过在 GetUserName 函数中做 while 循环,去不断检测所需的数据是否已返回,但这样开销太大。

于是想到了采用 AutoResetEvent。

 

  

 

ContractedBlock.gif ExpandedBlockStart.gif Code
        AutoResetEvent autoEvent = new AutoResetEvent(false); //将初始状态设置为非终止
        /// <summary>
        
/// 根据用户 ID 查询用户名
        
/// </summary>
        
/// <param name="id">用户 ID</param>
        
/// <returns>用户名</returns>
        public string GetUserName(int id)
        {
            
/*
             * 这里放置请求封包构造代码
             
*/
            
byte[] data=packet.GetData();
            s.Send(data);
            
if (autoEvent.WaitOne(5000false)) //这里定义了 5 秒的超时时间
            {
                
return result; //这个是示例,result 从 RecvUserName 中进行赋值
            }
            
else
            {
                
throw new Exception("服务器查询超时!");
            }
        }
        
/*
         *当 socket 读取线程读取到 Server 返回的用户名信息的封包头信息后调用 RecvUserName 函数
         * socket 读取线程部分代码略
         
*/
        
/// <summary>
        
/// 接收服务器返回信息
        
/// </summary>
        private void RecvUserName()
        {
            
/*
             * 这里编写封包拆解代码
             
*/
            result 
= username;
            autoEvent.Set(); 
//将事件状态设置为终止状态,允许等待线程继续。
        }

 

 

搞定!

这样的话 GetUserName 函数在执行 s.Send(data); 后会被挂起,直到超时或者 autoEvent 的事件状态被设置为终止状态。

然后才会执行之后的代码。

 

这样就能通过

string username=GetUserName(10); 这样的调用方式来返回用户名信息了。

 

这里只是简单说了下实现方法,其它具体的逻辑关系处理大家自己去想了,呵呵!

 

 

转载于:https://www.cnblogs.com/fp0991/archive/2008/09/05/1285092.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值