封装stream,在读写stream时提供事件通知_.Net教程
推荐:实例开发:ASP.NET创建网络相册在现在的数码时代,我们会经常拍摄一些相片以供留念,而随着数码照片的增多,往往需要很好地管理这些照片,以便更好地查阅留念。现在网上有不少的电子相册,都能很好的实现这些功能,那我们能否
前阵子的工作涉及一些网络编程,使用了面向流的方式做传输数据。在代码过程中,遇到一个新需求就是要统计流量。其实最简单的办法就时在读写流的地方增加代码,把功能增加上去就可以。但是我觉得那样对我原理的代码框架影响较大,基于尽量不影响原来的代码的考虑,我想到了Decorator设计模式。
先把代码贴出来,在做解释吧:
以下为引用的内容: public class EventStream : Stream { public event EventHandler<FStreamDataEventArgs> OnBeforeRead; public event EventHandler<FStreamDataEventArgs> OnBeforeWrite; private Stream stream; [ ==== Stream members ==== ]#region [ ==== Stream members ==== ] public override bool CanSeek public override bool CanWrite public override void Flush() public override long Length public override long Position public override int Read(byte[] buffer, int offset, int count) public override long Seek(long offset, SeekOrigin origin) public override void SetLength(long value) public override void Write(byte[] buffer, int offset, int count) public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, public override int EndRead(IAsyncResult asyncResult) public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) public override void EndWrite(IAsyncResult asyncResult) #endregion private class InternalCallback public InternalCallback(EventHandler<FStreamDataEventArgs> internalHandler, AsyncCallback callback) internal void Callback(IAsyncResult asyncResult) private class InternalAsyncState public object State public FStreamDataEventArgs StreamDataEventArgs public InternalAsyncState(FStreamDataEventArgs streamDataEventArgs, object state) private class EventStreamAsyncResult : IAsyncResult public EventStreamAsyncResult(IAsyncResult ar) public object AsyncState internal IAsyncResult InternalAsyncResult public System.Threading.WaitHandle AsyncWaitHandle public bool CompletedSynchronously public bool IsCompleted #endregion public class FStreamDataEventArgs : EventArgs public FStreamDataEventArgs(byte[] buffer, int offset, int count) this.buffer = buffer; /**//// <summary> /**//// <summary> /**//// <summary> |
刚开始以为很简单,事实上写下来还挺多行代码的,Decorator模式嘛,当然先继承stream,把stream本来该做的事情先完成了。这个很简单类里面包含一个内部的stream,stream该有的接口都由它来完成了。接下来就是增加两个事件,分别是OnBeforeRead、OnBeforeWrite。名字里面都有Before,其实我考虑到数据流都会通过这两个事件开放出来,你想做加密什么的都可以,当然也包括我想要的统计数据流量。
接下来就是在读写流的时候触发这两个事件就可以了。看看同步的Read、Write方法,简单的调用就可以了。
关键的地方就在于异步的读写。
我们先看看一般Stream的异步调用代码是怎么样的:
以下为引用的内容: stream.BeginRead(buffer, 0, byte2read, new AsyncCallback(EndReadCallback), state); private void EndReadCallback(IAsyncResult asyncResult) |
在不更改这个“client”代码的情况下,要怎么样在stream那边知道这里的确实读了多少数据呢?
显然在调用BeginRead的时候是不知道,那就只能对这个AsyncCallback做手脚了。可以预想到framework内部会在完成了Read的操作之后会调用AsyncCallback委托来通知结果。于是我就传一个我定义好的AsyncCallback委托给BeginRead。当然还要把“client”提供的AsyncCallback给包装起来,在做完我的事情(事件通知)之后,还是要把“client”要我办的事情给也给办了(调用"client"的AsyncCallback委托来通知结果)。
这就在实现了“在客户代码与framework之间插一脚”。
再来看看我是怎么做到事件通知的。首先要把我要的数据给传过去,于是有了InternalAsyncState,这里面要有我触发事件需要的事件参数,还应该要包括用户可能传入的state。具体大家看看InternalAsyncState的实现。
最后多考虑了一点就是,假如“client”代码不是像我写的那样,而是不断的通过检查Stream.BeginRead 方法返回的IAsyncResult的IsCompleted属性来确定是否Read完成的话,那我的代码就有问题了,我返回的IAsyncResult根本就不是原理的IAsyncResult了。EventStreamAsyncResult类就是为这个而写的。
下面是使用的代码:
以下为引用的内容: public void GetResponseStream() { EventStream es = new EventStream(tcpClient.NetStream); es.OnBeforeRead = new EventHandler<FStreamDataEventArgs>(EventStream_OnBeforeRead); es.OnBeforeWrite = new EventHandler<FStreamDataEventArgs>(EventStream_OnBeforeWrite); return es; } |
回头看看代码,其实都在用Decorator模式的思想,把原来的framework中的类都给包装起来,并在完成原来的功能之余另外加了自己的功能。
文笔一般,希望能对你有帮助。
分享:“黑盒测试管理”以外的编程经验片断除了很好地进行“黑盒测试管理”,个人觉得下述更值得用功;毕竟“前除后略”! 1、架构和算法的可行性测试分析:主要包括性能、并发等方面 2、CodeReview:很简单,但
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP发送Email实例(可带附件)
- js实现广告漂浮效果的小例子
- asp.net Repeater 数据绑定的具体实现
- Asp.Net 无刷新文件上传并显示进度条的实现方法及思路
- Asp.net获取客户端IP常见代码存在的伪造IP问题探讨
- VS2010 水晶报表的使用方法
- ASP.NET中操作SQL数据库(连接字符串的配置及获取)
- asp.net页面传值测试实例代码
- DataGridView - DataGridViewCheckBoxCell的使用介绍
- asp.net中javascript的引用(直接引入和间接引入)
- 三层+存储过程实现分页示例代码
- 相关链接:
- 教程说明:
.Net教程-封装stream,在读写stream时提供事件通知。