Example #1
0
 public void Enqueue(BackgroundTransferEntry entry)
 {
     lock (Queue)
     {
         Queue.Enqueue(entry);
     }
 }
Example #2
0
 private BackgroundTransferEntry GetNextEntry()
 {
     lock (Queue)
     {
         var item = Queue.Dequeue();
         CurrentEntry = item;
         return(item);
     }
 }
        public void Enqueue(BackgroundTransferEntry transfer)
        {
            lock (_syncRoot)
            {
                if (_disposedValue)
                {
                    throw new ObjectDisposedException("_queue");
                }

                _queue.Enqueue(transfer);
                _event.Set();
            }
        }
Example #4
0
        /// <inheritdoc />
        public async Task EnqueueAsync(IBackgroundTransfer backgroundTransfer, CancellationToken cancellationToken)
        {
            var sequenceNumber = Interlocked.Increment(ref _sequenceNumber);
            var newEntry       = new BackgroundTransferEntry(backgroundTransfer, sequenceNumber);

            lock (_pendingOrActiveEntries)
            {
                _pendingOrActiveEntries.Add(newEntry.Id, newEntry);
            }

            await _channel.Writer
            .WriteAsync(newEntry, cancellationToken)
            .ConfigureAwait(false);
        }
Example #5
0
        private async Task ExecuteAsync(BackgroundTransferEntry backgroundTransferEntry, CancellationToken cancellationToken)
        {
            using (_log?.BeginScope(
                       new Dictionary <string, object>
            {
                ["TransferId"] = backgroundTransferEntry.BackgroundTransfer.TransferId,
            }))
            {
                var backgroundTransfer = backgroundTransferEntry.BackgroundTransfer;
                _log?.LogInformation("Starting background transfer {0}", backgroundTransfer.TransferId);
                backgroundTransferEntry.Status = BackgroundTransferStatus.Transferring;

                // ReSharper disable once AccessToModifiedClosure
                var progress = new ActionProgress(sent => backgroundTransferEntry.Transferred = sent);
                try
                {
                    await backgroundTransfer.Start(progress, cancellationToken)
                    .ConfigureAwait(false);

                    _log?.LogInformation("Completed background transfer {0}", backgroundTransfer.TransferId);
                }
                catch (Exception ex) when(ex.Is <OperationCanceledException>())
                {
                    // Nothing to do
                    _log?.LogWarning("Background transfer {0} cancelled", backgroundTransfer.TransferId);
                }
                catch (Exception ex)
                {
                    // Show the error message
                    _log?.LogError(ex, "Background transfer {0} faulted", backgroundTransfer.TransferId);
                }
                finally
                {
                    lock (_pendingOrActiveEntries)
                    {
                        _pendingOrActiveEntries.Remove(backgroundTransferEntry.Id);
                    }

                    backgroundTransferEntry.Status = BackgroundTransferStatus.Finished;
                    backgroundTransfer.Dispose();
                }
            }
        }
Example #6
0
        private void ProcessQueue(CancellationToken cancellationToken)
        {
            var handles = new[]
            {
                cancellationToken.WaitHandle,
                _event,
            };

            _log?.LogDebug("Starting background transfer worker.");
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    var handleIndex = WaitHandle.WaitAny(handles);
                    if (handleIndex == 0)
                    {
                        break;
                    }

                    HasData = true;

                    try
                    {
                        BackgroundTransferEntry backgroundTransferEntry;
                        while ((backgroundTransferEntry = GetNextEntry()) != null)
                        {
                            var log = backgroundTransferEntry.Log;
                            var backgroundTransfer = backgroundTransferEntry.BackgroundTransfer;
                            try
                            {
                                var bt = backgroundTransfer;
                                log?.LogInformation("Starting background transfer {0}", bt.TransferId);
                                backgroundTransferEntry.Status = BackgroundTransferStatus.Transferring;

                                // ReSharper disable once AccessToModifiedClosure
                                var progress      = new ActionProgress(sent => backgroundTransferEntry.Transferred = sent);
                                var task          = bt.Start(progress, cancellationToken);
                                var cancelledTask = task
                                                    .ContinueWith(
                                    t =>
                                {
                                    // Nothing to do
                                    log?.LogWarning("Background transfer {0} cancelled", bt.TransferId);
                                },
                                    TaskContinuationOptions.OnlyOnCanceled);
                                var faultedTask = task
                                                  .ContinueWith(
                                    t =>
                                {
                                    log?.LogError(t.Exception, "Background transfer {0} faulted", bt.TransferId);
                                },
                                    TaskContinuationOptions.OnlyOnFaulted);
                                var completedTask = task
                                                    .ContinueWith(
                                    t =>
                                {
                                    // Nothing to do
                                    log?.LogInformation("Completed background transfer {0}", bt.TransferId);
                                },
                                    TaskContinuationOptions.NotOnCanceled);

                                try
                                {
                                    Task.WaitAll(cancelledTask, faultedTask, completedTask);
                                }
                                catch (AggregateException ex) when(ex.InnerExceptions.All(x => x is TaskCanceledException))
                                {
                                    // Ignore AggregateException when it only contains TaskCancelledException
                                }

                                log?.LogTrace("Background transfer {0} finished", bt.TransferId);
                            }
                            catch (Exception ex)
                            {
                                log?.LogError(ex, "Error during execution of background transfer {0}", backgroundTransfer.TransferId);
                            }
                            finally
                            {
                                backgroundTransfer.Dispose();
                            }

                            backgroundTransferEntry.Status = BackgroundTransferStatus.Finished;
                            CurrentEntry = null;
                        }
                    }
                    finally
                    {
                        HasData = false;
                    }
                }
                _log?.LogInformation("Cancellation requested - stopping background transfer worker.");
            }
            finally
            {
                _log?.LogDebug("Background transfer worker stopped.");
                Queue.Dispose();
            }
        }
Example #7
0
 private static BackgroundTransferInfo GetInfo(BackgroundTransferEntry entry)
 {
     return(new BackgroundTransferInfo(entry.Status, entry.BackgroundTransfer.TransferId, entry.Transferred));
 }