public void UpdateStatus(FileStatus status) { Status = status; DatabaseClient.UpdateFileStatus(ToDto()); }
public async Task DownloadAsync() { if (status == FileStatus.Finished) { throw new InvalidOperationException(); } if (status == FileStatus.Error) { Status = FileStatus.NotDownloaded; } try { var dir = Path.GetDirectoryName(FullFileName); Directory.CreateDirectory(dir); if (status == FileStatus.NotDownloaded) { File.WriteAllText(FullFileName + ".downloading", string.Empty); UpdateStatus(FileStatus.Downloading); var numChunks = (Size + WebServiceClient.CHUNKSIZE - 1) / WebServiceClient.CHUNKSIZE; for (var i = 0; i < numChunks; i++) { Chunks.Add(new ChunkModel { FileId = Id, Id = i, Status = ChunkStatus.New, }); } DatabaseClient.SaveChunks(Chunks); } else if (status == FileStatus.Downloading) { } using (var fs = new FileStream(FullFileName + ".downloading", FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 4096, FileOptions.Asynchronous | FileOptions.RandomAccess)) { var tasks = Chunks.Where(ch => ch.Status == ChunkStatus.New).Select(ch => WebServiceClient.GetChunk(this, ch.Id)); var working = new List <Task <Tuple <int, byte[]> > >(); foreach (var task in tasks) { if (working.Count < 5) { working.Add(task); } else { var finished = await Task.WhenAny(working); working.Remove(finished); working.Add(task); await ContinueWith(await finished); } } while (working.Count > 0) { var finished = await Task.WhenAny(working); working.Remove(finished); await ContinueWith(await finished); } async Task ContinueWith(Tuple <int, byte[]> finished) { fs.Seek(WebServiceClient.CHUNKSIZE * finished.Item1, SeekOrigin.Begin); await fs.WriteAsync(finished.Item2, 0, finished.Item2.Length); Chunks[finished.Item1].UpdateStatus(ChunkStatus.Done); FinishedSize += finished.Item2.Length; } } DatabaseClient.DeleteChunks(Chunks); if (Md5.Equals(Util.GetFileMd5(FullFileName + ".downloading"), StringComparison.InvariantCultureIgnoreCase)) { UpdateStatus(FileStatus.Finished); } else { UpdateStatus(FileStatus.Error); } } catch (WebException) { Status = FileStatus.Error; } }
public void UpdateStatus(ChunkStatus status) { Status = status; DatabaseClient.UpdateChunk(this); }