异步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();
                }
            }
        }




    }
posted @ 2011-04-26 00:00  吾爱易逝  阅读(2479)  评论(0编辑  收藏  举报