日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

封裝stream,在讀寫stream時提供事件通知_.Net教程

編輯Tag賺U幣
教程Tag:暫無Tag,歡迎添加,賺取U幣!

推薦:實例開發(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;
public EventStream(Stream stream)
{
if (stream == null) throw new ArgumentNullException("EventStream");
this.stream = stream;
}

[ ==== Stream members ==== ]#region [ ==== Stream members ==== ]
public override bool CanRead
{
get { return stream.CanRead; }
}

public override bool CanSeek
{
get { return stream.CanSeek; }
}

public override bool CanWrite
{
get { return stream.CanWrite; }
}

public override void Flush()
{
stream.Flush();
}

public override long Length
{
get { return stream.Length; }
}

public override long Position
{
get
{
return stream.Position;
}
set
{
stream.Position = value;
}
}

public override int Read(byte[] buffer, int offset, int count)
{
int readSize = stream.Read(buffer, offset, count);
if (OnBeforeRead != null)
OnBeforeRead(this, new FStreamDataEventArgs(buffer, offset, readSize));
return readSize;
}

public override long Seek(long offset, SeekOrigin origin)
{
return stream.Seek(offset, origin);
}

public override void SetLength(long value)
{
stream.SetLength(value);
}

public override void Write(byte[] buffer, int offset, int count)
{
if (OnBeforeWrite != null)
OnBeforeWrite(this, new FStreamDataEventArgs(buffer, offset, count));
stream.Write(buffer, offset, count);
}

public override IAsyncResult BeginRead(byte[] buffer, int offset, int count,
AsyncCallback callback, object state)
{
InternalAsyncState myState = new InternalAsyncState(
new FStreamDataEventArgs(buffer, offset, count), state);
AsyncCallback myCallback = new AsyncCallback(
new InternalCallback(OnBeforeRead, callback).Callback);
return new EventStreamAsyncResult(
stream.BeginRead(buffer, offset, count, myCallback, myState));
}

public override int EndRead(IAsyncResult asyncResult)
{
EventStreamAsyncResult esar = asyncResult as EventStreamAsyncResult;
if (esar != null)
return stream.EndRead(esar.InternalAsyncResult);
else
return stream.EndRead(asyncResult);
}

public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
{
InternalAsyncState myState = new InternalAsyncState(
new FStreamDataEventArgs(buffer, offset, count), state);
AsyncCallback myCallback = new AsyncCallback(
new InternalCallback(OnBeforeWrite, callback).Callback);
return new EventStreamAsyncResult(
stream.BeginWrite(buffer, offset, count, myCallback, myState));
}

public override void EndWrite(IAsyncResult asyncResult)
{
stream.EndWrite(asyncResult);
}

#endregion

private class InternalCallback
{
private AsyncCallback callback;
private EventHandler<FStreamDataEventArgs> internalHandler;

public InternalCallback(EventHandler<FStreamDataEventArgs> internalHandler, AsyncCallback callback)
{
this.internalHandler = internalHandler;
this.callback = callback;
}

internal void Callback(IAsyncResult asyncResult)
{
InternalAsyncState myState = asyncResult.AsyncState as InternalAsyncState;
if (internalHandler != null && myState != null)
internalHandler(this, myState.StreamDataEventArgs);
callback(new EventStreamAsyncResult(asyncResult));
}
}

private class InternalAsyncState
{
object state;
FStreamDataEventArgs streamDataEventArgs;

public object State
{
get { return state; }
}

public FStreamDataEventArgs StreamDataEventArgs
{
get { return streamDataEventArgs; }
}

public InternalAsyncState(FStreamDataEventArgs streamDataEventArgs, object state)
{
this.streamDataEventArgs = streamDataEventArgs;
this.state = state;
}
}

private class EventStreamAsyncResult : IAsyncResult
{
IAsyncResult ar;

public EventStreamAsyncResult(IAsyncResult ar)
{
if (ar == null) throw new ArgumentNullException("EventStreamAsyncResult");
this.ar = ar;
}
IAsyncResult Members#region IAsyncResult Members

public object AsyncState
{
get
{
InternalAsyncState myState = ar.AsyncState as InternalAsyncState;
if (myState != null)
return myState.State;
else
return ar.AsyncState;
}
}

internal IAsyncResult InternalAsyncResult
{
get { return ar; }
}

public System.Threading.WaitHandle AsyncWaitHandle
{
get { return ar.AsyncWaitHandle; }
}

public bool CompletedSynchronously
{
get { return ar.CompletedSynchronously; }
}

public bool IsCompleted
{
get { return ar.IsCompleted; }
}

#endregion
}
}

public class FStreamDataEventArgs : EventArgs
{
private byte[] buffer;
private int offset;
private int count;

public FStreamDataEventArgs(byte[] buffer, int offset, int count)
{
if(buffer == null) throw new ArgumentNullException("FStreamDataEventArgs");
if(offset count>buffer.Length) throw new ArgumentOutOfRangeException("FStreamDataEventArgs");

this.buffer = buffer;
this.offset = offset;
this.count = count;
}

/**//// <summary>
/// 數(shù)據(jù)緩存
/// </summary>
public byte[] Buffer
{
get { return buffer; }
}

/**//// <summary>
/// 數(shù)據(jù)開始位置
/// </summary>
public int Offset
{
get { return offset; }
}

/**//// <summary>
/// 數(shù)據(jù)長度
/// </summary>
public int Count
{
get { return count; }
}
}

剛開始以為很簡單,事實上寫下來還挺多行代碼的,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)
{
object state = asyncResult.AsyncState;
nReadSize = stream.EndRead(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:很簡單,但

來源:模板無憂//所屬分類:.Net教程/更新時間:2008-08-22
相關(guān).Net教程