コード例 #1
0
 /// <summary>
 /// 获取下载完成的文件长度
 /// </summary>
 /// <returns></returns>
 public long GetDownloadedLength()
 {
     lock (_locker)
     {
         return(DownloadSegmentList.Sum(downloadSegment => downloadSegment.DownloadedLength));
     }
 }
コード例 #2
0
 /// <summary>
 /// 是否下载完成
 /// </summary>
 /// <returns></returns>
 public bool IsFinished()
 {
     lock (_locker)
     {
         return(DownloadSegmentList.TrueForAll(segment => segment.Finished));
     }
 }
コード例 #3
0
 /// <summary>
 /// 获取当前所有下载段
 /// </summary>
 /// <returns></returns>
 public IReadOnlyList <DownloadSegment> GetCurrentDownloadSegmentList()
 {
     lock (_locker)
     {
         return(DownloadSegmentList.ToList());
     }
 }
コード例 #4
0
        /// <summary>
        /// 注册下载段
        /// </summary>
        /// <param name="downloadSegment"></param>
        public void RegisterDownloadSegment(DownloadSegment downloadSegment)
        {
            downloadSegment.Message = "Start RegisterDownloadSegment";
            lock (_locker)
            {
                // 找到顺序
                var n = DownloadSegmentList.FindIndex(temp => temp.StartPoint > downloadSegment.StartPoint);
                if (n < 0)
                {
                    // 找不到一个比他大的,放在最后面
                    DownloadSegmentList.Add(downloadSegment);
                }
                else
                {
                    // 原本是按照顺序的,找到第一个比他大的,放在前面
                    DownloadSegmentList.Insert(n, downloadSegment);
                }

                downloadSegment.Number = DownloadSegmentList.Count;

                downloadSegment.SegmentManager = this;
            }

            downloadSegment.Message = "Finish RegisterDownloadSegment";
        }
コード例 #5
0
        /// <summary>
        /// 写入文件,可不等待
        /// </summary>
        /// <param name="fileStartPoint">从文件的哪里开始写</param>
        /// <param name="data">写入的数据</param>
        /// <param name="dataOffset"></param>
        /// <param name="dataLength"></param>
        public async Task WriteAsync(long fileStartPoint, byte[] data, int dataOffset, int dataLength)
        {
            var task = new TaskCompletionSource <bool>();

            var fileSegment = new FileSegment(fileStartPoint, data, dataOffset, dataLength, task);

            DownloadSegmentList.Enqueue(fileSegment);
            await task.Task;
        }
コード例 #6
0
        public void RegisterDownloadSegment(DownloadSegment downloadSegment)
        {
            lock (_locker)
            {
                // 找到顺序
                var n = DownloadSegmentList.FindIndex(temp => temp.StartPoint > downloadSegment.StartPoint);
                if (n < 0)
                {
                    DownloadSegmentList.Add(downloadSegment);
                }
                else
                {
                    DownloadSegmentList.Insert(n, downloadSegment);
                }

                downloadSegment.Number = DownloadSegmentList.Count;

                downloadSegment.SegmentManager = this;
            }
        }
コード例 #7
0
        private async Task WriteToFile()
        {
            while (true)
            {
                var fileSegment = await DownloadSegmentList.DequeueAsync();

                try
                {
                    Stream.Seek(fileSegment.FileStartPoint, SeekOrigin.Begin);

                    await Stream.WriteAsync(fileSegment.Data, fileSegment.DataOffset, fileSegment.DataLength);
                }
                catch (Exception e)
                {
                    Exception = e;
                    WriteFinished?.Invoke(this, EventArgs.Empty);
                    return;
                }

                try
                {
                    fileSegment.TaskCompletionSource?.SetResult(true);
                }
                catch (Exception)
                {
                    // 执行业务代码
                }

                var isEmpty = DownloadSegmentList.Count == 0;

                if (isEmpty)
                {
                    WriteFinished?.Invoke(this, EventArgs.Empty);
                    if (_isDispose)
                    {
                        return;
                    }
                }
            }
        }