Beispiel #1
0
        public async Task RunAsync(CancellationToken token)
        {
            if (!_fileInfo.Exists)
            {
                throw new FileNotFoundException(_fileInfo.FullName);
            }

            IsActive = true;

            try
            {
                //validate cancellation before making the API call
                token.ThrowIfCancellationRequested();
                var job = (State.Status == JobStatus.Pending.ToString())
                    ? await CreateNewJob() : LoadJobFromState();

                using (var fs = _fileInfo.OpenRead())
                {
                    var item = new UploadItem
                    {
                        ContentLength = _fileInfo.Length,
                        DataStream    = fs
                    };

                    //if this is a resumed job, we need to set the stream position
                    if (State.Status != JobStatus.Pending.ToString())
                    {
                        item.DataStream.Position = job.CurrentPosition;
                    }

                    UpdateProgress(job, item);

                    while (job.CurrentPosition < _fileInfo.Length)
                    {
                        //validate cancellation before making the API call
                        token.ThrowIfCancellationRequested();

                        //upload next chunk
                        await _client.UploadChunkAsync(job, item);

                        //update the manifest
                        State.CurrentPosition = job.CurrentPosition;
                        State.ProcessedAt     = DateTime.UtcNow;

                        UpdateProgress(job, item);
                    }

                    //validate cancellation before making the API call
                    token.ThrowIfCancellationRequested();
                    var archiveId = await _client.FinishUploadAsync(job, item);

                    //mark manifest on complete
                    State.Status          = JobStatus.Completed.ToString();
                    State.CurrentPosition = job.CurrentPosition;
                    State.ProcessedAt     = DateTime.UtcNow;
                    State.ArchiveId       = archiveId;

                    fs.Close();
                    UpdateProgress(job, item);
                }

                CleanUp();
            }
            catch (Exception ex)
            {
                HasFailed = true;
                Exception = ex;

                //update manifest to indicate failure
                State.Status      = JobStatus.Failed.ToString();
                State.ProcessedAt = DateTime.UtcNow;
            }

            IsActive = false;
        }