public void Enqueue(BackgroundTransferEntry entry) { lock (Queue) { Queue.Enqueue(entry); } }
private BackgroundTransferEntry GetNextEntry() { lock (Queue) { var item = Queue.Dequeue(); CurrentEntry = item; return(item); } }
public void Enqueue([NotNull] BackgroundTransferEntry transfer) { lock (_syncRoot) { if (_disposedValue) { throw new ObjectDisposedException("_queue"); } _queue.Enqueue(transfer); _event.Set(); } }
/// <summary> /// Enqueue a new <see cref="IBackgroundTransfer"/> for the given <paramref name="connection"/> /// </summary> /// <param name="backgroundTransfer">The background transfer to enqueue</param> /// <param name="connection">The connection to enqueue the background transfer for</param> public void EnqueueBackgroundTransfer([NotNull] IBackgroundTransfer backgroundTransfer, [CanBeNull] FtpConnection connection) { var entry = new BackgroundTransferEntry(backgroundTransfer, connection?.Log); BackgroundTransferWorker.Enqueue(entry); }
private void ProcessQueue(CancellationToken cancellationToken) { var handles = new[] { cancellationToken.WaitHandle, _event }; _log?.Debug("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) { Debug.Assert(backgroundTransferEntry != null, "backgroundTransferEntry must not be null (internal error)"); var log = backgroundTransferEntry.Log; var backgroundTransfer = backgroundTransferEntry.BackgroundTransfer; try { var bt = backgroundTransfer; log?.Info("Starting background transfer {0}", bt.TransferId); backgroundTransferEntry.Status = BackgroundTransferStatus.Transferring; var task = bt.Start(cancellationToken); var cancelledTask = task .ContinueWith( t => { // Nothing to do log?.Warn("Background transfer {0} cancelled", bt.TransferId); }, TaskContinuationOptions.OnlyOnCanceled); var faultedTask = task .ContinueWith( t => { log?.Error(t.Exception, "Background transfer {0} faulted", bt.TransferId); }, TaskContinuationOptions.OnlyOnFaulted); var completedTask = task .ContinueWith( t => { // Nothing to do log?.Info("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?.Trace("Background transfer {0} finished", bt.TransferId); } catch (Exception ex) { log?.Error(ex, "Error during execution of background transfer {0}", backgroundTransfer.TransferId); } finally { backgroundTransfer.Dispose(); } backgroundTransferEntry.Status = BackgroundTransferStatus.Finished; CurrentEntry = null; } } finally { HasData = false; } } _log?.Info("Cancellation requested - stopping background transfer worker."); } finally { _log?.Debug("Background transfer worker stopped."); Queue.Dispose(); } }
/// <inheritdoc /> public void EnqueueBackgroundTransfer(IBackgroundTransfer backgroundTransfer, IFtpConnection connection) { var entry = new BackgroundTransferEntry(backgroundTransfer, connection?.Log); BackgroundTransferWorker.Enqueue(entry); }
private BackgroundTransferEntry GetNextEntry() { lock (Queue) { var item = Queue.Dequeue(); CurrentEntry = item; return item; } }
private void ProcessQueue(CancellationToken cancellationToken) { var handles = new[] { cancellationToken.WaitHandle, _event }; _log?.Debug("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) { Debug.Assert(backgroundTransferEntry != null, "backgroundTransferEntry must not be null (internal error)"); var log = backgroundTransferEntry.Log; var backgroundTransfer = backgroundTransferEntry.BackgroundTransfer; try { var bt = backgroundTransfer; log?.Info("Starting background transfer {0}", bt.TransferId); backgroundTransferEntry.Status = BackgroundTransferStatus.Transferring; var task = bt.Start(cancellationToken); var cancelledTask = task .ContinueWith( t => { // Nothing to do log?.Warn("Background transfer {0} cancelled", bt.TransferId); }, TaskContinuationOptions.OnlyOnCanceled); var faultedTask = task .ContinueWith( t => { log?.Error(t.Exception, "Background transfer {0} faulted", bt.TransferId); }, TaskContinuationOptions.OnlyOnFaulted); var completedTask = task .ContinueWith( t => { // Nothing to do log?.Info("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?.Trace("Background transfer {0} finished", bt.TransferId); } catch (Exception ex) { log?.Error(ex, "Error during execution of background transfer {0}", backgroundTransfer.TransferId); } finally { backgroundTransfer.Dispose(); } backgroundTransferEntry.Status = BackgroundTransferStatus.Finished; CurrentEntry = null; } } finally { HasData = false; } } _log?.Info("Cancellation requested - stopping background transfer worker."); } finally { _log?.Debug("Background transfer worker stopped."); Queue.Dispose(); } }