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(BackgroundTransferEntry transfer) { lock (_syncRoot) { if (_disposedValue) { throw new ObjectDisposedException("_queue"); } _queue.Enqueue(transfer); _event.Set(); } }
/// <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); }
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(); } } }
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(); } }
private static BackgroundTransferInfo GetInfo(BackgroundTransferEntry entry) { return(new BackgroundTransferInfo(entry.Status, entry.BackgroundTransfer.TransferId, entry.Transferred)); }