private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.Canceled) { _items.RemoveAt(i--); try { _eventAggregator.Publish(new DownloadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } bool canceled; ProcessFilePart(part, part.ParentItem.DCId, part.ParentItem.InputLocation, out canceled); if (canceled) { lock (_itemsSyncRoot) { part.ParentItem.Canceled = true; part.Status = PartStatus.Processed; _items.Remove(part.ParentItem); } return; } // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; var data = part.File.Bytes.Data; if (data.Length < part.Limit.Value && (part.Number + 1) != part.ParentItem.Parts.Count) { var complete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!complete) { var emptyBufferSize = part.Limit.Value - data.Length; var position = data.Length; var missingPart = new DownloadablePart(part.ParentItem, new TLInt(position), new TLInt(emptyBufferSize), -part.Number); var currentItemIndex = part.ParentItem.Parts.IndexOf(part); part.ParentItem.Parts.Insert(currentItemIndex + 1, missingPart); } } isCanceled = part.ParentItem.Canceled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = (double)downloadedCount / count; } else { _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { byte[] bytes = { }; foreach (var p in part.ParentItem.Parts) { bytes = TLUtils.Combine(bytes, p.File.Bytes.Data); } //part.ParentItem.Location.Buffer = bytes; var fileName = part.ParentItem.FileName.ToString(); StringLocker.Lock(fileName, () => FileUtils.WriteBytes(fileName, bytes)); if (part.ParentItem.Callback != null) { Execute.BeginOnThreadPool(() => { part.ParentItem.Callback.SafeInvoke(part.ParentItem); if (part.ParentItem.Callbacks != null) { foreach (var callback in part.ParentItem.Callbacks) { callback.SafeInvoke(part.ParentItem); } } }); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(part.ParentItem)); } } else { //Execute.BeginOnThreadPool(() => _eventAggregator.Publish(new ProgressChangedEventArgs(part.ParentItem, progress))); } } }