示例#1
0
文件: FileModel.cs 项目: sdjnyty/amt
 public void UpdateStatus(FileStatus status)
 {
     Status = status;
     DatabaseClient.UpdateFileStatus(ToDto());
 }
示例#2
0
文件: FileModel.cs 项目: sdjnyty/amt
        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;
            }
        }
示例#3
0
 public void UpdateStatus(ChunkStatus status)
 {
     Status = status;
     DatabaseClient.UpdateChunk(this);
 }