Example #1
0
        private async Task Download(FSItem item, Stream result, Downloader downloader)
        {
            try
            {
                Log.Trace($"Started download: {item.Name} - {item.Id}");
                var       start          = Stopwatch.StartNew();
                var       buf            = new byte[64 << 10];
                var       uncommitedSize = 0;
                const int commitSize     = 512 << 10;

                using (result)
                    using (var writer = new BufferedStream(result))
                    {
                        OnDownloadStarted?.Invoke(item);
                        while (writer.Length < item.Length)
                        {
                            var stream = await cloud.Files.Download(item.Id);

                            stream.Position = writer.Length;
                            int red;
                            do
                            {
                                red = await stream.ReadAsync(buf, 0, buf.Length);

                                if (writer.Length == 0)
                                {
                                    Log.Trace($"Got first part: {item.Name} - {item.Id} in {start.ElapsedMilliseconds}");
                                }

                                await writer.WriteAsync(buf, 0, red);

                                uncommitedSize += red;
                                if (uncommitedSize <= commitSize)
                                {
                                    continue;
                                }

                                uncommitedSize = 0;
                                await writer.FlushAsync();

                                downloader.Downloaded = writer.Length;
                            }while (red > 0);
                        }

                        await writer.FlushAsync();

                        downloader.Downloaded = writer.Length;
                    }

                Log.Trace($"Finished download: {item.Name} - {item.Id}");
                OnDownloaded?.Invoke(item);
                BoschHelper.Decrypt(downloader.Path);

                if (access.TryAdd(
                        item.Id,
                        new CacheEntry {
                    Id = item.Id, AccessTime = DateTime.UtcNow, Length = item.Length
                }))
                {
                    TotalSizeIncrease(item.Length);
                }

                if (TotalSize > CacheSize)
                {
                    var task = cleanSizeWorker.Run(TotalSize - CacheSize);
                }

                if (start.ElapsedMilliseconds > 29000)
                {
                    Log.Warn($"Downloading {item.Path} took: {start.ElapsedMilliseconds}");
                }
            }
            catch (Exception ex)
            {
                Log.ErrorTrace($"Download failed: {item.Name} - {item.Id}\r\n{ex}");
                await downloader.Failed();

                OnDownloadFailed?.Invoke(item);
            }
            finally
            {
                lock (DownloadersLock)
                {
                    Downloaders.Remove(item.Path);
                }
            }
        }