Ejemplo n.º 1
0
        public Downloader Add(ResourceLocation rl, ResourceLocation[] mirrors, string localFile, List <Segment> segments, RemoteFileInfo remoteInfo, int requestedSegmentCount, bool autoStart, DateTime createdDateTime)
        {
            Downloader d = new Downloader(rl, mirrors, localFile, segments, remoteInfo, requestedSegmentCount, createdDateTime);

            Add(d, autoStart);

            return(d);
        }
Ejemplo n.º 2
0
        private void RestartDownload()
        {
            int            currentTry = 0;
            Stream         stream;
            RemoteFileInfo newInfo;

            do
            {
                lastError = null;

                SetState(DownloaderState.Preparing);

                currentTry++;
                try
                {
                    newInfo = defaultDownloadProvider.GetFileInfo(this.ResourceLocation, out stream);

                    break;
                }
                catch (Exception ex)
                {
                    lastError = ex;
                    if (currentTry < Settings.Default.InitialMaxRetries)
                    {
                        SetState(DownloaderState.WaitingForReconnect);
                        Thread.Sleep(TimeSpan.FromSeconds(Settings.Default.InitialRetryDelay));
                    }
                    else
                    {
                        lastError = ex;
                        SetState(DownloaderState.EndedWithError);
                        return;
                    }
                }
            }while (true);

            SetState(DownloaderState.Prepared);

            try
            {
                // check if the file changed on the server
                if (!newInfo.AcceptRanges ||
                    newInfo.LastModified > RemoteFileInfo.LastModified ||
                    newInfo.FileSize != RemoteFileInfo.FileSize)
                {
                    this.remoteFileInfo = newInfo;
                    StartSegments(this.RequestedSegments, stream);
                }
                else
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }

                    RunSegments();
                }
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception ex)
            {
                lastError = ex;
                SetState(DownloaderState.EndedWithError);
            }
        }
Ejemplo n.º 3
0
        private void SegmentThreadProc(object objSegment)
        {
            Segment segment = (Segment)objSegment;

            segment.LastError = null;

            try
            {
                if (segment.EndPosition > 0 && segment.StartPosition >= segment.EndPosition)
                {
                    segment.State = SegmentState.Finished;

                    // raise the event
                    OnSegmentStoped(segment);

                    return;
                }

                int    buffSize = 8192;
                byte[] buffer   = new byte[buffSize];

                segment.State = SegmentState.Connecting;

                // raise the event
                OnSegmentStarting(segment);

                if (segment.InputStream == null)
                {
                    // get the next URL (It can the the main url or some mirror)
                    ResourceLocation location = this.MirrorSelector.GetNextResourceLocation();
                    // get the protocol provider for that mirror
                    IProtocolProvider provider = location.BindProtocolProviderInstance(this);

                    while (location != this.ResourceLocation)
                    {
                        Stream tempStream;

                        // get the remote file info on mirror
                        RemoteFileInfo tempRemoteInfo = provider.GetFileInfo(location, out tempStream);
                        if (tempStream != null)
                        {
                            tempStream.Dispose();
                        }

                        // check if the file on mirror is the same
                        if (tempRemoteInfo.FileSize == remoteFileInfo.FileSize &&
                            tempRemoteInfo.AcceptRanges == remoteFileInfo.AcceptRanges)
                        {
                            // if yes, stop looking for the mirror
                            break;
                        }

                        lock (mirrors)
                        {
                            // the file on the mirror is not the same, so remove from the mirror list
                            mirrors.Remove(location);
                        }

                        // the file on the mirror is different
                        // so get other mirror to use in the segment
                        location = this.MirrorSelector.GetNextResourceLocation();
                        provider = location.BindProtocolProviderInstance(this);
                    }

                    // get the input stream from start position
                    segment.InputStream = provider.CreateStream(location, segment.StartPosition, segment.EndPosition);

                    // change the segment URL to the mirror URL
                    segment.CurrentURL = location.URL;
                }
                else
                {
                    //  change the segment URL to the main URL
                    segment.CurrentURL = this.resourceLocation.URL;
                }

                using (segment.InputStream)
                {
                    // raise the event
                    OnSegmentStarted(segment);

                    // change the segment state
                    segment.State      = SegmentState.Downloading;
                    segment.CurrentTry = 0;

                    long readSize;

                    do
                    {
                        // reads the buffer from input stream
                        readSize = segment.InputStream.Read(buffer, 0, buffSize);

                        // check if the segment has reached the end
                        if (segment.EndPosition > 0 &&
                            segment.StartPosition + readSize > segment.EndPosition)
                        {
                            // adjust the 'readSize' to write only necessary bytes
                            readSize = (segment.EndPosition - segment.StartPosition);
                            if (readSize <= 0)
                            {
                                segment.StartPosition = segment.EndPosition;
                                break;
                            }
                        }

                        // locks the stream to avoid that other threads changes
                        // the position of stream while this thread is writing into the stream
                        lock (segment.OutputStream)
                        {
                            segment.OutputStream.Position = segment.StartPosition;
                            segment.OutputStream.Write(buffer, 0, (int)readSize);
                        }

                        // increse the start position of the segment and also calculates the rate
                        segment.IncreaseStartPosition(readSize);

                        // check if the stream has reached its end
                        if (segment.EndPosition > 0 && segment.StartPosition >= segment.EndPosition)
                        {
                            segment.StartPosition = segment.EndPosition;
                            break;
                        }

                        // check if the user have requested to pause the download
                        if (state == DownloaderState.Pausing)
                        {
                            segment.State = SegmentState.Paused;
                            break;
                        }

                        //Thread.Sleep(1500);
                    }while (readSize > 0);

                    // Fix from code project:
                    // http://www.codeproject.com/Messages/4730070/A-bug-fix.aspx
                    if (segment.State == SegmentState.Downloading &&
                        segment.StartPosition != segment.EndPosition)
                    {
                        Debug.WriteLine("Probably stream read has been timeout.");
                        throw new Exception("Probably stream read has been timeout.");
                    }

                    if (segment.State == SegmentState.Downloading)
                    {
                        segment.State = SegmentState.Finished;

                        // try to create other segment,
                        // spliting the missing bytes from one existing segment
                        AddNewSegmentIfNeeded();
                    }
                }

                // raise the event
                OnSegmentStoped(segment);
            }
            catch (Exception ex)
            {
                // store the error information
                segment.State     = SegmentState.Error;
                segment.LastError = ex;

                Debug.WriteLine(ex.ToString());

                // raise the event
                OnSegmentFailed(segment);
            }
            finally
            {
                // clean up the segment
                segment.InputStream = null;
            }
        }
Ejemplo n.º 4
0
        private void StartDownloadThreadProc(object objSegmentCount)
        {
            SetState(DownloaderState.Preparing);

            int    segmentCount = Math.Min((int)objSegmentCount, Settings.Default.MaxSegments);
            Stream inputStream  = null;
            int    currentTry   = 0;

            do
            {
                lastError = null;

                if (state == DownloaderState.Pausing)
                {
                    SetState(DownloaderState.NeedToPrepare);
                    return;
                }

                SetState(DownloaderState.Preparing);

                currentTry++;
                try
                {
                    remoteFileInfo = defaultDownloadProvider.GetFileInfo(this.ResourceLocation, out inputStream);
                    break;
                }
                catch (ThreadAbortException)
                {
                    SetState(DownloaderState.NeedToPrepare);
                    return;
                }
                catch (Exception ex)
                {
                    lastError = ex;
                    if (currentTry < Settings.Default.InitialMaxRetries)
                    {
                        SetState(DownloaderState.WaitingForReconnect);
                        Thread.Sleep(TimeSpan.FromSeconds(Settings.Default.InitialRetryDelay));
                    }
                    else
                    {
                        lastError = ex;
                        SetState(DownloaderState.EndedWithError);
                        return;
                    }
                }
            }while (true);

            try
            {
                lastError = null;
                StartSegments(segmentCount, inputStream);
            }
            catch (ThreadAbortException)
            {
                throw;
            }
            catch (Exception ex)
            {
                lastError = ex;
                SetState(DownloaderState.EndedWithError);
            }
        }