private void createNewThreadIfRequired() { lock (GlobalLock.Locker) { if (FlagStop) { return; } if (Info == null || !Info.AcceptRanges) { return; } var realNofMaxThread = Info.AcceptRanges ? NofThread : 1; var nofCurrentThreads = (Ranges.Count(x => !x.IsIdle)); var reqThreads = realNofMaxThread - nofCurrentThreads; if (reqThreads > 0) { var avRanges = Ranges.Where(x => !x.IsDownloaded); if (avRanges.Any(x => x.IsIdle)) { var first = avRanges.First(x => x.IsIdle); if (first.TotalBytesReceived > 0) { var fstart = first.Remaining.Start; var fend = first.Remaining.End; first.End = fstart - 1; var next = new HttpRange(fstart, fend, RangeDir, Guid.NewGuid().ToString("N")); Ranges.Add(next); var cd = CreateNewRangeDownloader(next); cd.Download(); } else { if (!first.IsIdle) { return; } var rdlist = cdList.Where(x => x.Range.FileId == first.FileId); if (rdlist.Any()) { var cd = rdlist.First(); if (!cd.Range.IsIdle) { return; } cd.Reset(); cd.UseChunk = this.UseChunk; cd.Download(); } else { var cd = CreateNewRangeDownloader(first); cd.Download(); } } } //10kb is for secure downloading without no corruption //If a range < 10kb there is no dividing else if (avRanges.Any(x => x.Remaining.Size > 10 * 1024)) { var temp = avRanges.Where(x => x.Remaining.Size > 10 * 1024); var first = avRanges.OrderByDescending(x => x.Remaining.Size).First(); var fstart = first.End - first.Remaining.Size / 2; var fend = first.End; first.End = fstart - 1; var next = new HttpRange(fstart, fend, RangeDir, Guid.NewGuid().ToString("N")); Ranges.Add(next); var cd = CreateNewRangeDownloader(next); cd.Download(); } } else if (reqThreads < 0) { var temp = cdList.Where(x => !x.Range.IsDownloaded && !x.Range.IsIdle); if (temp.Any()) { var first = temp.OrderByDescending(x => x.Range.Remaining.Size).First(); first.Stop(); } } } }
internal HttpRangeDownloader(HttpRange range, HttpDownloadInfo info = null) { Range = range; Info = info; UseChunk = true; }