public class Rqt_Request
{
public Rqt_Request()
{
this.URI = string.Empty;
this.Cache = HttpRequestCacheLevel.CacheIfAvailable;
this.Timeout = 0xea60;
this.Query = string.Empty;
CookieContainer container = new CookieContainer();
this.Cookies = container;
this.Token = new CancellationToken();
}
public Rqt_Request(string uri, HttpRequestCacheLevel cache, int timeout, string query, CancellationToken token, object state, CookieContainer cookies)
{
this.URI = string.Empty;
this.Cache = HttpRequestCacheLevel.CacheIfAvailable;
this.Timeout = 0xea60;
this.Query = string.Empty;
CookieContainer container = new CookieContainer();
this.Cookies = container;
this.Token = new CancellationToken();
this.URI = uri;
this.Cache = cache;
this.Timeout = timeout;
this.Token = token;
this.State = RuntimeHelpers.GetObjectValue(state);
this.Query = query;
if (cookies != null)
{
this.Cookies = cookies;
}
}
public HttpRequestCacheLevel Cache
{
get;
set;
}
public CookieContainer Cookies
{
get;
set;
}
public string Query
{
get;
set;
}
public object State
{
get;
set;
}
public int Timeout
{
get;
set;
}
public CancellationToken Token
{
get;
set;
}
public string URI
{
get;
set;
}
}
public class Rqt_State : IDisposable
{
private int _bufferSize;
private string _host;
private string _Uri;
private object _writeLock;
private MemoryStream _WriteStream;
private bool disposedValue;
public Rqt_State()
{
this._host = string.Empty;
this._bufferSize = 0;
this._writeLock = new object();
this._Uri = "";
this._WriteStream = new MemoryStream();
this.Status = RequestStatus.NotStarted;
}
~Rqt_State()
{
Dispose(true);
}
public Rqt_State(Rqt_Async owner, int buffersize)
: this()
{
this._bufferSize = buffersize;
this.BufferBytes = new byte[this._bufferSize + 1];
this.Owner = owner;
}
public void AppendStream(int numbytes)
{
this.WriteStream.Write(this.BufferBytes, 0, numbytes);
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
if (this.WriteStream != null)
{
this.WriteStream.Dispose();
}
if (this.BufferStream != null)
{
this.BufferStream.Dispose();
}
}
this._WriteStream = null;
this.BufferStream = null;
this.Request = null;
this.Response = null;
this.BufferBytes = null;
}
this.disposedValue = true;
}
internal byte[] BufferBytes
{
get;
set;
}
internal Stream BufferStream
{
get;
set;
}
public System.Exception Exception
{
get;
set;
}
public string Host
{
get
{
return this._host;
}
}
public bool IsTimedOut
{
get;
set;
}
public Rqt_Async Owner
{
get;
set;
}
public HttpWebRequest Request
{
get;
set;
}
public HttpWebResponse Response
{
get;
set;
}
public Image ResponseImage
{
get
{
try
{
return Image.FromStream(this.ResponseStream);
}
catch (System.Exception exception1)
{
ProjectData.SetProjectError(exception1);
System.Exception exception = exception1;
}
return null;
}
}
public MemoryStream ResponseStream
{
get
{
MemoryStream stream = new MemoryStream();
this.WriteStream.WriteTo(stream);
stream.Position = 0L;
return stream;
}
}
public string ResponseText
{
get
{
string str = string.Empty;
try
{
StreamReader reader = new StreamReader(this.ResponseStream, true);
str = reader.ReadToEnd();
reader.Close();
}
catch (System.Exception exception1)
{
ProjectData.SetProjectError(exception1);
System.Exception exception = exception1;
}
return str;
}
}
public object State
{
get;
set;
}
public RequestStatus Status
{
get;
set;
}
public CancellationToken Token
{
get;
set;
}
public string Uri
{
get
{
return this._Uri;
}
set
{
this._Uri = value;
try
{
this._host = new System.Uri(this._Uri).Host;
}
catch (System.Exception exception1)
{
ProjectData.SetProjectError(exception1);
System.Exception exception = exception1;
}
}
}
public MemoryStream WriteStream
{
get
{
object expression = this._writeLock;
ObjectFlowControl.CheckForSyncLockOnValueType(expression);
lock (expression)
{
return this._WriteStream;
}
}
}
}
/// <summary>
/// 异步请求
/// </summary>
public class Rqt_Async
{
#region 变量
private static List<string> _Cached = new List<string>();
private ManualResetEvent allDone;
private int BUFFER_SIZE;
#endregion
#region 静态事件
public delegate void OnPhaseChangeEventHandler(Rqt_Async sender, RequestPhase e);
private static OnPhaseChangeEventHandler OnPhaseChangeEvent;
public static event OnPhaseChangeEventHandler OnPhaseChange
{
add { Rqt_Async.OnPhaseChangeEvent += value; }
remove { Rqt_Async.OnPhaseChangeEvent -= value; }
}
#endregion
#region 事件
public delegate void OnCancelEventHandler(Rqt_Async sender);
private OnCancelEventHandler OnCancelEvent;
public event OnCancelEventHandler OnCancel
{
add { this.OnCancelEvent += value; }
remove { this.OnCancelEvent -= value; }
}
protected delegate void OnChangedEventHandler(Rqt_Async sender, RequestEventType status);
private OnChangedEventHandler OnChangedEvent;
protected event OnChangedEventHandler OnChanged
{
add { this.OnChangedEvent += value; }
remove { this.OnChangedEvent -= value; }
}
public delegate void OnErrorEventHandler(Rqt_Async sender);
private OnErrorEventHandler OnErrorEvent;
public event OnErrorEventHandler OnError
{
add { this.OnErrorEvent += value; }
remove { this.OnErrorEvent -= value; }
}
public delegate void OnFinishedEventHandler(Rqt_Async sender);
private OnFinishedEventHandler OnFinishedEvent;
public event OnFinishedEventHandler OnFinished
{
add { this.OnFinishedEvent += value; }
remove { this.OnFinishedEvent -= value; }
}
public delegate void OnSuccessEventHandler(Rqt_Async sender);
private OnSuccessEventHandler OnSuccessEvent;
public event OnSuccessEventHandler OnSuccess
{
add { this.OnSuccessEvent += value; }
remove { this.OnSuccessEvent -= value; }
}
public delegate void OnUpdateEventHandler(Rqt_Async sender);
private OnUpdateEventHandler OnUpdateEvent;
public event OnUpdateEventHandler OnUpdate
{
add { this.OnUpdateEvent += value; }
remove { this.OnUpdateEvent -= value; }
}
#endregion
#region 构造函数
public Rqt_Async()
{
this.OnChanged += (s, e) => Changed(s, e);
this.Finished = new ManualResetEvent(false);
this.allDone = new ManualResetEvent(false);
this.BUFFER_SIZE = 0x80000;
this.EnableRaisingEvents = true;
}
public Rqt_Async(object owner)
: this()
{
this.Owner = owner;
}
#endregion
#region 属性
public static List<string> Cached
{
[MethodImpl(MethodImplOptions.Synchronized)]
get
{
return _Cached;
}
}
public Rqt_State CurrentRequest
{
get;
set;
}
public bool EnableRaisingEvents
{
get;
set;
}
public ManualResetEvent Finished
{
get;
set;
}
public object Owner
{
get;
set;
}
#endregion
protected void Changed(Rqt_Async sender, RequestEventType event_type)
{
if (this.EnableRaisingEvents)
{
switch (((int)event_type))
{
case 0:
{
if (OnErrorEvent != null)
{
OnErrorEvent(sender);
}
break;
}
case 1:
{
if (OnSuccessEvent != null)
{
OnSuccessEvent(sender);
}
break;
}
case 2:
{
if (OnCancelEvent != null)
{
OnCancelEvent(sender);
}
break;
}
case 3:
{
if (OnUpdateEvent != null)
{
OnUpdateEvent(sender);
}
break;
}
case 4:
{
if (OnFinishedEvent != null)
{
OnFinishedEvent(sender);
}
break;
}
}
}
}
/// <summary>
/// 从缓存获取请求数据
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
private bool GetFromCache(Rqt_State state)
{
bool flag=false;
WebRequest wr = WebRequest.Create(state.Uri);
wr.Timeout = 0x1388;
wr.CachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheOnly);
try
{
WebResponse response = wr.GetResponse();
if (response.IsFromCache)
{
state.Response = (HttpWebResponse)response;
state.Request = (HttpWebRequest)wr;
response.GetResponseStream().CopyTo(state.WriteStream);
flag = true;
}
}
catch (Exception ex)
{
flag = false;
Console.WriteLine(ex.Message);
}
return flag;
}
/// <summary>
/// 异步读取回调函数
/// </summary>
/// <param name="asyncResult"></param>
internal void ReadCallBack(IAsyncResult asyncResult)
{
Rqt_State state = (Rqt_State)asyncResult.AsyncState;
try
{
state.Token.ThrowIfCancellationRequested();
if (OnPhaseChangeEvent != null)
{
OnPhaseChangeEvent(this, RequestPhase.Read);
}
Stream bufferStream = state.BufferStream;
int numbytes = bufferStream.EndRead(asyncResult);
if (numbytes > 0)
{
state.AppendStream(numbytes);
if (OnChangedEvent != null)
{
OnChangedEvent(this, RequestEventType.Update);
}
IAsyncResult result = bufferStream.BeginRead(state.BufferBytes, 0, this.BUFFER_SIZE, new AsyncCallback(this.ReadCallBack), state);
return;
}
state.Status = RequestStatus.Succeded;
bufferStream.Close();
}
catch (Exception ex)
{
SetRequestStateError(state, ref ex);
}
this.allDone.Set();
}
/// <summary>
/// 释放状态
/// </summary>
public void ReleaseState()
{
if (this.CurrentRequest != null)
{
this.CurrentRequest.Dispose();
}
this.CurrentRequest = null;
}
/// <summary>
/// 异步请求完成时的回调函数
/// </summary>
/// <param name="asynchronousResult"></param>
internal void RespCallback(IAsyncResult asynchronousResult)
{
Rqt_State asyncState = (Rqt_State)asynchronousResult.AsyncState;
try
{
asyncState.Token.ThrowIfCancellationRequested();
HttpWebRequest request = asyncState.Request;
asyncState.Response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream responseStream = asyncState.Response.GetResponseStream();
asyncState.BufferStream = responseStream;
IAsyncResult result = responseStream.BeginRead(asyncState.BufferBytes, 0, this.BUFFER_SIZE, new AsyncCallback(this.ReadCallBack), asyncState);
return;
}
catch (Exception ex)
{
SetRequestStateError(asyncState, ref ex);
}
this.allDone.Set();
}
private static void SetRequestStateError(Rqt_State requestState, ref Exception ex)
{
RequestStatus status = RequestStatus.Exception;
if (requestState.Token.IsCancellationRequested)
{
ex = null;
requestState.Request.Abort();
status = RequestStatus.Canceled;
}
else if (requestState.IsTimedOut)
{
ex = new TimeoutException();
status = RequestStatus.Exception;
}
requestState.Status = status;
requestState.Exception = ex;
}
/// <summary>
/// 开始异步访问
/// </summary>
/// <param name="r"></param>
internal virtual void Start(Rqt_Request r)
{
this.Start(r.URI, r.State, r.Token, (RequestCacheLevel)r.Cache, r.Cookies, r.Query, r.Timeout);
}
/// <summary>
/// 开始异步访问
/// </summary>
/// <param name="uri"></param>
/// <param name="state"></param>
/// <param name="ct"></param>
/// <param name="cache"></param>
/// <param name="cookies"></param>
/// <param name="PostQuery"></param>
/// <param name="Timeout"></param>
internal virtual void Start(string uri, object state, CancellationToken ct, RequestCacheLevel cache, CookieContainer cookies, string PostQuery, int Timeout)
{
this.allDone = new ManualResetEvent(false);
this.Finished = new ManualResetEvent(false);
this.CurrentRequest = new Rqt_State(this, this.BUFFER_SIZE);
try
{
this.CurrentRequest.Token = ct;
this.CurrentRequest.Uri = uri;
this.CurrentRequest.State = state;
#region 从缓存读取数据
if (((cache == RequestCacheLevel.Default) | (cache == RequestCacheLevel.CacheIfAvailable)) | (cache == RequestCacheLevel.CacheOnly))
{
if (Cached.Contains(this.CurrentRequest.Uri) && this.GetFromCache(this.CurrentRequest))
{
if (ct.IsCancellationRequested)
{
this.CurrentRequest.Status = RequestStatus.Canceled;
}
else
{
this.CurrentRequest.Status = RequestStatus.Succeded;
}
this.allDone.Set();
}
cache = RequestCacheLevel.Reload;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.CurrentRequest.Uri);
Network.RequestInitialize(request);
request.CookieContainer = cookies;
request.CachePolicy = new RequestCachePolicy(cache);
if (!string.IsNullOrEmpty(PostQuery))
{
byte[] bytes = Encoding.UTF8.GetBytes(PostQuery);
if (bytes.Length > 0)
{
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = bytes.Length;
request.GetRequestStream().Write(bytes, 0, bytes.Length);
}
}
this.CurrentRequest.Request = request;
this.CurrentRequest.Status = RequestStatus.Running;
if (OnPhaseChangeEvent != null)
{
OnPhaseChangeEvent(this, RequestPhase.Begin);
}
WaitHandle wh=request.BeginGetResponse(new AsyncCallback(this.RespCallback), this.CurrentRequest).AsyncWaitHandle;
RegisteredWaitHandle handle = ThreadPool.RegisterWaitForSingleObject(wh,
new WaitOrTimerCallback(Rqt_Async.TimeoutCallback), this.CurrentRequest, Timeout, true);
if (OnPhaseChangeEvent != null)
{
OnPhaseChangeEvent(this, RequestPhase.Wait);
}
this.allDone.WaitOne();
if (OnPhaseChangeEvent != null)
{
OnPhaseChangeEvent(this, RequestPhase.End);
}
#endregion
}
catch (Exception ex)
{
this.CurrentRequest.Status = RequestStatus.Exception;
this.CurrentRequest.Exception = ex;
}
finally
{
if (this.CurrentRequest.Response != null)
{
this.CurrentRequest.Response.Close();
}
}
switch (this.CurrentRequest.Status)
{
case RequestStatus.Succeded:
if (!Cached.Contains(this.CurrentRequest.Uri))
{
Cached.Add(this.CurrentRequest.Uri);
}
if (OnChangedEvent != null)
{
OnChangedEvent(this, RequestEventType.Success);
}
break;
case RequestStatus.Canceled:
Cached.Remove(this.CurrentRequest.Uri);
if (OnChangedEvent != null)
{
OnChangedEvent(this, RequestEventType.Canceled);
}
break;
case RequestStatus.Exception:
Cached.Remove(this.CurrentRequest.Uri);
if (OnChangedEvent != null)
{
OnChangedEvent(this, RequestEventType.Exception);
}
break;
}
this.Finished.Set();
if (OnChangedEvent != null)
{
OnChangedEvent(this, RequestEventType.Finished);
}
}
/// <summary>
/// 异步请求超时回调函数
/// </summary>
/// <param name="state"></param>
/// <param name="timedOut"></param>
internal static void TimeoutCallback(object state, bool timedOut)
{
if (timedOut)
{
Rqt_State state2 = (Rqt_State)state;
if ((state2 != null) && (state2.Request != null))
{
state2.IsTimedOut = true;
state2.Request.Abort();
}
}
}
}