Initial commit
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
using SharepointToolbox.Web.Core.Models;
|
||||
|
||||
namespace SharepointToolbox.Web.Services;
|
||||
|
||||
public static class BulkOperationRunner
|
||||
{
|
||||
public static async Task<BulkOperationSummary<TItem>> RunAsync<TItem>(
|
||||
IReadOnlyList<TItem> items,
|
||||
Func<TItem, int, CancellationToken, Task> processItem,
|
||||
IProgress<OperationProgress> progress,
|
||||
CancellationToken ct,
|
||||
int maxConcurrency = 1)
|
||||
{
|
||||
if (items.Count == 0)
|
||||
{
|
||||
progress.Report(new OperationProgress(0, 0, "Nothing to do."));
|
||||
return new BulkOperationSummary<TItem>(Array.Empty<BulkItemResult<TItem>>());
|
||||
}
|
||||
|
||||
progress.Report(new OperationProgress(0, items.Count, $"Processing 1/{items.Count}..."));
|
||||
var results = new BulkItemResult<TItem>[items.Count];
|
||||
int completed = 0;
|
||||
|
||||
async Task RunOne(int i, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
await processItem(items[i], i, token);
|
||||
results[i] = BulkItemResult<TItem>.Success(items[i]);
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
results[i] = BulkItemResult<TItem>.Failed(items[i], ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
int done = Interlocked.Increment(ref completed);
|
||||
progress.Report(new OperationProgress(done, items.Count, $"Processed {done}/{items.Count}"));
|
||||
}
|
||||
}
|
||||
|
||||
if (maxConcurrency <= 1)
|
||||
{
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
await RunOne(i, ct);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var options = new ParallelOptions { MaxDegreeOfParallelism = maxConcurrency, CancellationToken = ct };
|
||||
await Parallel.ForEachAsync(Enumerable.Range(0, items.Count), options,
|
||||
async (i, token) => await RunOne(i, token));
|
||||
}
|
||||
|
||||
progress.Report(new OperationProgress(items.Count, items.Count, "Complete."));
|
||||
return new BulkOperationSummary<TItem>(results);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user