上篇通过两个单向通道模拟异步请求、应答。实现繁琐,且握手过程依赖于启动顺序(服务器启动,客户端启动,客户端连接服务器,服务器连接客户端,通信。。)
 
改进他
 
使用本地异步模式,典型的有
 
使用 <?XML:NAMESPACE PREFIX = MSHelp NS = "http://msdn.microsoft.com/mshelp" /> 对象的异步操作。
使用事件的异步操作。
 
 
本则通过 IAsyncResult 对象 + 请求应答模式实现非阻塞服务调用
 
 
工程结构描述
server 提供服务
protocal 服务协议
client 服务使用者
 
 
涉及到的类型
indata输入结构化数据
iser 服务协议
outdata 输出结构化数据
ser 服务实现
iwriter 接受信息显示
 
 
关键代码段
 
InBlock.gif服务实现部分,模拟服务计算,延迟 5s 返回    
InBlock.gif
InBlock.gif                public outdata work(indata data)
InBlock.gif                {
InBlock.gif                        System.Threading.Thread.Sleep(5000);
InBlock.gif
InBlock.gif                        var res = new outdata();
InBlock.gif                        res.s = string.Format("[{0}]", data.s);
InBlock.gif                        return res;
InBlock.gif                }
InBlock.gif
InBlock.gif服务调用部分,采用异步模式
InBlock.gif
InBlock.gif
InBlock.gif             void work()
InBlock.gif                {
InBlock.gif                        var res = new indata();
InBlock.gif                        res.s = richTextBox1.Text;
InBlock.gif
InBlock.gif                        ser.Beginwork(res, new AsyncCallback(_work_Callback), null);
InBlock.gif                }
InBlock.gif
InBlock.gif                void _work_Callback(IAsyncResult ar)
InBlock.gif                {
InBlock.gif                        var res = ser.Endwork(ar);
InBlock.gif                        write(res.s);
InBlock.gif                }
InBlock.gif
 
 
流程
服务器启动服务
客户端连接服务器服务
客户端请求服务
客户端显示服务结果
 
操作
在界面输入框输入信息 xxx,点击 work,5s 后返回服务器处理结果  [xxx],并显示
 
 
说明
 
为了说明界面线程真的没有阻塞,通过定时器在界面线程刷新当前时间(如果阻塞了时间部分不会刷新)
 
采用 winform 客户端,增加可操作性
 
异步对象执行在线程池线程,返回结果需在 UI  线程显示,需调用 UI 异步版本执行函数 Invoke ,具体代码如下:
 
InBlock.gifiwriter 成员#region iwriter 成员
InBlock.gif
InBlock.gif                public void write(string s)
InBlock.gif                {
InBlock.gif                        this.richTextBox1.Invoke(new Action<string>(_write), s);
InBlock.gif                }
InBlock.gif
InBlock.gif                void _write(string s)
InBlock.gif                {
InBlock.gif                        this.richTextBox1.Text = s;
InBlock.gif                }
InBlock.gif
InBlock.gif                #endregion