private void DownloadingThread(CancellationToken token) { for (; ;) { if (token.WaitHandle.WaitOne(1000 * 10)) { return; } var items = new List <DownloadItemInfo>(); lock (_lockObject) { items.AddRange(CollectionUtils.Unite(_volatileDownloadItemInfoManager, _downloadItemInfoManager).ToArray() .Where(n => n.State == DownloadState.Downloading)); } foreach (var item in items) { try { if (!this.CheckSize(item)) { throw new ArgumentException("download size too large."); } if (item.Depth == 0) { if (!_cacheManager.Contains(item.Clue.Hash)) { item.State = DownloadState.Downloading; _networkManager.Download(item.Clue.Hash); } else { item.State = DownloadState.Decoding; } } else { if (!item.Index.Groups.All(n => _existManager.GetCount(n, true) >= n.Hashes.Count() / 2)) { item.State = DownloadState.Downloading; foreach (var group in item.Index.Groups.Randomize()) { if (_existManager.GetCount(group, true) >= group.Hashes.Count() / 2) { continue; } foreach (var hash in _existManager.GetHashes(group, false)) { _networkManager.Download(hash); } } } else { item.State = DownloadState.ParityDecoding; } } } catch (Exception e) { item.State = DownloadState.Error; Log.Error(e); } } } }