/// <summary> /// Refreshes the cache for the given set of files if expired /// </summary> public async Task RefreshCacheAsync(IEnumerable <CacheFileMetadata> librariesCacheMetadata, ILogger logger, CancellationToken cancellationToken) { await ParallelUtility.ForEachAsync(DownloadFileIfNecessaryAsync, MaxConcurrentDownloads, librariesCacheMetadata, cancellationToken).ConfigureAwait(false); async Task DownloadFileIfNecessaryAsync(CacheFileMetadata metadata) { if (!File.Exists(metadata.DestinationPath)) { logger.Log(string.Format(Resources.Text.DownloadingFile, metadata.Source), LogLevel.Operation); await DownloadToFileAsync(metadata.Source, metadata.DestinationPath, attempts : 5, cancellationToken : cancellationToken).ConfigureAwait(false); } } }
public async Task ForEachAsync_CancellationTokenSet_DoesNotRunAllTasks() { int counter = 0; var cts = new CancellationTokenSource(); Exception exception = await Assert.ThrowsExceptionAsync <TaskCanceledException>(async() => await ParallelUtility.ForEachAsync((i) => { if (i % 2 == 0) { cts.Cancel(); } counter++; return(Task.CompletedTask); }, 1, Enumerable.Range(1, 3), cts.Token) ); Assert.AreEqual(2, counter); // both 1 and 2 ran, but operation was cancelled before 3 }
public async Task ForEachAsync_IfMultipleTasksFail_AllTasksGetRun_OnlyFirstExceptionIsReported() { int counter = 0; Exception exception = await Assert.ThrowsExceptionAsync <Exception>(async() => await ParallelUtility.ForEachAsync((i) => { if (i % 2 == 0) { throw new Exception($"Expected Failure (iteration {i})"); } counter++; return(Task.CompletedTask); }, 1, Enumerable.Range(1, 5)) ); Assert.AreEqual("Expected Failure (iteration 2)", exception.Message); Assert.AreEqual(3, counter); // both 1, 3, and 5 ran, 2 and 4 threw the exception }
public async Task ForEachAsync_IfOneTaskFails_AllTasksGetRun() { int counter = 0; Exception exception = await Assert.ThrowsExceptionAsync <Exception>(async() => await ParallelUtility.ForEachAsync((i) => { if (i % 2 == 0) { throw new Exception("Expected Failure"); } counter++; return(Task.CompletedTask); }, 1, Enumerable.Range(1, 3)) ); Assert.AreEqual("Expected Failure", exception.Message); Assert.AreEqual(2, counter); // both 1 and 3 ran, 2 threw the exception }
public async Task ForEachAsync_ValidEmptyArguments_ShouldRunWithoutExceptions() { await ParallelUtility.ForEachAsync((i) => Task.CompletedTask, 1, Array.Empty <object>()); }
public async Task ForEachAsync_NullItems_ShouldThrow() { await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => await ParallelUtility.ForEachAsync((i) => Task.CompletedTask, 1, (object[])null) ); }
public async Task ForEachAsync_NegativeDegreesParallelism_ShouldThrow() { await Assert.ThrowsExceptionAsync <ArgumentOutOfRangeException>(async() => await ParallelUtility.ForEachAsync((i) => Task.CompletedTask, -5, Array.Empty <object>()) ); }
public async Task ForEachAsync_NullAction_ShouldThrow() { await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => await ParallelUtility.ForEachAsync(null, 1, Array.Empty <object>()) ); }