public void Dispose()
        {
            this.disposed = true;
            this.info.ProgressCallback -= this.progressCB;
            this.downloadTimer.Dispose();
            this.info.Dispose();

            this.progressCB        = null;
            this.allDownloadedData = null;
            this.downloadTimer     = null;
            this.info = null;
        }
        private void ReadCallBack(IAsyncResult asyncResult)
        {
            lock (this.downloadAbortLock)
            {
                if (this.disposed || this.downloadAborted)
                {
                    return;
                }

                // Get the DownloadInfo object from AsyncResult.
                DownloadInfo info = (DownloadInfo)asyncResult.AsyncState;
                if (info == null)
                {
                    Abort();
                }

                // Retrieve the ResponseStream that was set in RespCallback.
                Stream responseStream = info.ResponseStream;
                if (responseStream == null)
                {
                    Abort();
                }

                // Read info.BufferRead to verify that it contains data.
                int bytesRead = responseStream.EndRead(asyncResult);
                if (bytesRead > 0)
                {
                    if (info.useFastBuffers)
                    {
                        System.Array.Copy(info.BufferRead, 0,
                                          info.dataBufferFast, info.bytesProcessed,
                                          bytesRead);
                    }
                    else
                    {
                        for (int b = 0; b < bytesRead; b++)
                        {
                            info.dataBufferSlow.Add(info.BufferRead[b]);
                        }
                    }
                    info.bytesProcessed += bytesRead;

                    // Perhaps we didn't originally get the content size, so we're
                    // just reading data with no end in sight.  If that's the casre,
                    // abort the download if we cross the max download size.
                    if (info.bytesProcessed > MaxDownloadSizeInBytes)
                    {
                        //System.Console.WriteLine("Download has become too big, aborting");
                        Abort();
                        return;
                    }

                    // If a registered progress-callback, inform it of our
                    // download progress so far.
                    if ((info.ProgressCallback != null) && (!this.downloadAborted))
                    {
                        info.ProgressCallback(info.Request.RequestUri.AbsoluteUri, info.bytesProcessed, info.dataLength);
                    }

                    // Continue reading data until responseStream.EndRead returns –1.
                    IAsyncResult ar = responseStream.BeginRead(
                        info.BufferRead, 0, BUFFER_SIZE,
                        new AsyncCallback(ReadCallBack), info);
                }
                else
                {
                    // We're done, signal completion
                    allDone.Set();
                }
            }
        }
        private void ResponseCallback(IAsyncResult ar)
        {
            if (this.disposed || this.downloadAborted)
            {
                return;
            }

            // Get the DownloadInfo object from the async result were
            // we're storing all of the temporary data and the download
            // buffer.
            DownloadInfo info = (DownloadInfo)ar.AsyncState;

            try
            {
                // Get the WebRequest from RequestState.
                WebRequest req = info.Request;

                // Call EndGetResponse, which produces the WebResponse object
                // that came from the request issued above.
                WebResponse resp = req.EndGetResponse(ar);

                // Find the data size from the headers.
                string strContentLength = resp.Headers["Content-Length"];
                if (strContentLength != null)
                {
                    info.dataLength = Convert.ToInt32(strContentLength);
                    //System.Console.WriteLine("Size: " + info.dataLength + " for " + this.url);

                    if (info.dataLength > MaxDownloadSizeInBytes)
                    {
                        //System.Console.WriteLine("Download is too big, aborting");
                        Abort();
                        return;
                    }

                    info.dataBufferFast = new byte[info.dataLength];
                }
                else
                {
                    info.useFastBuffers = false;
                    info.dataBufferSlow = new System.Collections.ArrayList(BUFFER_SIZE);
                }

                //  Start reading data from the response stream.
                Stream ResponseStream = resp.GetResponseStream();

                // Store the response stream in RequestState to read
                // the stream asynchronously.
                info.ResponseStream = ResponseStream;

                //  Pass do.BufferRead to BeginRead.
                IAsyncResult iarRead = ResponseStream.BeginRead(info.BufferRead,
                                                                0,
                                                                BUFFER_SIZE,
                                                                new AsyncCallback(ReadCallBack),
                                                                info);
            }
            catch (WebException)
            {
                info.connectionFailed = true;
            }
            catch (Exception)
            {
                info.connectionFailed = true;
            }
            finally
            {
                if (info.connectionFailed)
                {
                    Abort();
                }
            }
        }