封裝stream,在讀寫stream時提供事件通知_.Net教程
推薦:實例開發(fā):ASP.NET創(chuàng)建網(wǎng)絡(luò)相冊在現(xiàn)在的數(shù)碼時代,我們會經(jīng)常拍攝一些相片以供留念,而隨著數(shù)碼照片的增多,往往需要很好地管理這些照片,以便更好地查閱留念。現(xiàn)在網(wǎng)上有不少的電子相冊,都能很好的實現(xiàn)這些功能,那我們能否
前陣子的工作涉及一些網(wǎng)絡(luò)編程,使用了面向流的方式做傳輸數(shù)據(jù)。在代碼過程中,遇到一個新需求就是要統(tǒng)計流量。其實最簡單的辦法就時在讀寫流的地方增加代碼,把功能增加上去就可以。但是我覺得那樣對我原理的代碼框架影響較大,基于盡量不影響原來的代碼的考慮,我想到了Decorator設(shè)計模式。
先把代碼貼出來,在做解釋吧:
| 以下為引用的內(nèi)容: 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模式嘛,當(dāng)然先繼承stream,把stream本來該做的事情先完成了。這個很簡單類里面包含一個內(nèi)部的stream,stream該有的接口都由它來完成了。接下來就是增加兩個事件,分別是OnBeforeRead、OnBeforeWrite。名字里面都有Before,其實我考慮到數(shù)據(jù)流都會通過這兩個事件開放出來,你想做加密什么的都可以,當(dāng)然也包括我想要的統(tǒng)計數(shù)據(jù)流量。
接下來就是在讀寫流的時候觸發(fā)這兩個事件就可以了�?纯赐降腞ead、Write方法,簡單的調(diào)用就可以了。
關(guān)鍵的地方就在于異步的讀寫。
我們先看看一般Stream的異步調(diào)用代碼是怎么樣的:
| 以下為引用的內(nèi)容: stream.BeginRead(buffer, 0, byte2read, new AsyncCallback(EndReadCallback), state); private void EndReadCallback(IAsyncResult asyncResult) |
在不更改這個“client”代碼的情況下,要怎么樣在stream那邊知道這里的確實讀了多少數(shù)據(jù)呢?
顯然在調(diào)用BeginRead的時候是不知道,那就只能對這個AsyncCallback做手腳了�?梢灶A(yù)想到framework內(nèi)部會在完成了Read的操作之后會調(diào)用AsyncCallback委托來通知結(jié)果。于是我就傳一個我定義好的AsyncCallback委托給BeginRead。當(dāng)然還要把“client”提供的AsyncCallback給包裝起來,在做完我的事情(事件通知)之后,還是要把“client”要我辦的事情給也給辦了(調(diào)用"client"的AsyncCallback委托來通知結(jié)果)。
這就在實現(xiàn)了“在客戶代碼與framework之間插一腳”。
再來看看我是怎么做到事件通知的。首先要把我要的數(shù)據(jù)給傳過去,于是有了InternalAsyncState,這里面要有我觸發(fā)事件需要的事件參數(shù),還應(yīng)該要包括用戶可能傳入的state。具體大家看看InternalAsyncState的實現(xiàn)。
最后多考慮了一點就是,假如“client”代碼不是像我寫的那樣,而是不斷的通過檢查Stream.BeginRead 方法返回的IAsyncResult的IsCompleted屬性來確定是否Read完成的話,那我的代碼就有問題了,我返回的IAsyncResult根本就不是原理的IAsyncResult了。EventStreamAsyncResult類就是為這個而寫的。
下面是使用的代碼:
| 以下為引用的內(nèi)容: 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中的類都給包裝起來,并在完成原來的功能之余另外加了自己的功能。
文筆一般,希望能對你有幫助。
分享:“黑盒測試管理”以外的編程經(jīng)驗片斷除了很好地進行“黑盒測試管理”,個人覺得下述更值得用功;畢竟“前除后略”! 1、架構(gòu)和算法的可行性測試分析:主要包括性能、并發(fā)等方面 2、CodeReview:很簡單,但
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發(fā)送Email實例(可帶附件)
- js實現(xiàn)廣告漂浮效果的小例子
- asp.net Repeater 數(shù)據(jù)綁定的具體實現(xiàn)
- Asp.Net 無刷新文件上傳并顯示進度條的實現(xiàn)方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報表的使用方法
- ASP.NET中操作SQL數(shù)據(jù)庫(連接字符串的配置及獲取)
- asp.net頁面?zhèn)髦禍y試實例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲過程實現(xiàn)分頁示例代碼
- 相關(guān)鏈接:
- 教程說明:
.Net教程-封裝stream,在讀寫stream時提供事件通知
。