异步WebRequest用法

    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();

                }

            }

        }









    }

你可能感兴趣的:(request)