Beispiel #1
0
        private static DownloadTask SafeDequeue(Queue <DownloadTask> queues)
        {
            DownloadTask downloadTask = null;

            lock (queues)
            {
                try
                {
                    downloadTask = queues.Dequeue();
                }
                catch (Exception ex)
                {
                    //ignore
                }
            }
            return(downloadTask);
        }
Beispiel #2
0
 private static Task StartNextTask(Queue <DownloadTask> queues)
 {
     if (queues.Count <= 0)
     {
         return(null);
     }
     return(Task.Run(async() =>
     {
         DownloadTask downloadTask = SafeDequeue(queues);
         if (downloadTask != null)
         {
             await downloadTask.StartAsync();
         }
         while (queues.Count > 0)
         {
             DownloadTask nextTask = SafeDequeue(queues);
             if (nextTask != null)
             {
                 await nextTask.StartAsync();
             }
         }
     }));
 }
Beispiel #3
0
        public static DownloadTask DownloadAsync(this DownloadSegmentInfo downloadInfo,
                                                 Action <long, float> progressAction, CancellationToken cancellationToken = default)
        {
            Pipe pipeline            = new Pipe();
            bool isCompleted         = false;
            var  downloadTask        = new DownloadTask(downloadInfo);
            Func <List <Task> > func = new Func <List <Task> >(() =>
            {
                var readTask = Task.Run(async() =>
                {
                    int bytesRead;
                    try
                    {
                        if (downloadInfo.Percentage >= 100)
                        {
                            return;
                        }
                        if (downloadInfo.Size != 0 && downloadInfo.TotalReadBytes == downloadInfo.Size)
                        {
                            return;
                        }
                        if (downloadInfo.SrcStream == null)
                        {
                            var httpClient = HttpClientFactory.Instance.GetHttpClient(downloadInfo.Url);
                            if (downloadInfo.Size != 0)
                            {
                                httpClient.DefaultRequestHeaders.Range = new RangeHeaderValue(downloadInfo.TotalReadBytes, downloadInfo.Size);
                            }
                            var response           = await httpClient.GetAsync(downloadInfo.Url);
                            downloadInfo.SrcStream = await response.Content.ReadAsStreamAsync();
                            var size = response.Content.Headers.ContentLength.GetValueOrDefault();
                            if (size > 0 && downloadInfo.Size == 0)
                            {
                                downloadInfo.Size = size;
                                if (downloadInfo.End == 0)
                                {
                                    downloadInfo.End = downloadInfo.Start + size;
                                }
                            }
                            if (downloadInfo.TotalReadBytes > 0)
                            {
                                ///设置文件流写入位置
                                downloadInfo.DstStream.Position = downloadInfo.Start + downloadInfo.TotalReadBytes;
                            }
                        }

                        while (true) // Where the downloading part is happening
                        {
                            bytesRead = await downloadInfo.SrcStream.ReadAsync(pipeline.Writer.GetMemory(), cancellationToken);
                            if (bytesRead <= 0)
                            {
                                break;
                            }
                            pipeline.Writer.Advance(bytesRead);
                            var flushResult = await pipeline.Writer.FlushAsync(cancellationToken);
                            if (flushResult.IsCanceled)
                            {
                                break;
                            }
                            if (flushResult.IsCompleted)
                            {
                                break;
                            }
                        }
                        pipeline.Writer.Complete();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    finally
                    {
                        isCompleted = true;
                    }
                }, cancellationToken);

                var writeTask = Task.Run(async() =>
                {
                    float percentage = 0;
                    long bytesRead   = 0;
                    try
                    {
                        while (true)
                        {
                            var readResult = await pipeline.Reader.ReadAsync(cancellationToken);
                            foreach (var segment in readResult.Buffer)
                            {
                                bytesRead += segment.Length;
                                await downloadInfo.DstStream.WriteAsync(segment, cancellationToken);
                            }
                            downloadInfo.TotalReadBytes += bytesRead;
                            if (bytesRead > 0)//有进度才会提示
                            {
                                percentage = downloadInfo.Percentage;
                                progressAction.Invoke(bytesRead, percentage); // To Get the current percentage.
                                bytesRead = 0;
                            }
                            pipeline.Reader.AdvanceTo(readResult.Buffer.End);
                            if (readResult.IsCompleted || readResult.IsCanceled)
                            {
                                break;
                            }
                            if (isCompleted)
                            {
                                break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    finally
                    {
                        isCompleted = true;
                        downloadTask.Close();
                    }
                    pipeline.Reader.Complete();
                }, cancellationToken);

                return(new List <Task>()
                {
                    readTask, writeTask
                });
            });

            downloadTask.Create(func);
            return(downloadTask);
        }