Skip to content

Instantly share code, notes, and snippets.

@jamescurran
Last active December 26, 2021 13:10
Show Gist options
  • Save jamescurran/46d90e84646c3c308cdea0d664addd1d to your computer and use it in GitHub Desktop.
Save jamescurran/46d90e84646c3c308cdea0d664addd1d to your computer and use it in GitHub Desktop.
// Copyright (c) 2019-2020 James M. Curran/Novel Theory LLC. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace NovelTheory.Common
{
public class TaskCollection
{
private bool _frozen = false;
private readonly object _lockList = new object();
private List<Task> _tasks = new List<Task>();
public static TaskCollection operator +(TaskCollection coll, Task task)
{
if (coll._frozen)
throw new InvalidOperationException("Cannot add to collection once Wait is started.");
lock(coll._lockList)
coll._tasks.Add(task);
return coll;
}
/// <summary>
/// Creates a task that will complete when all in Task objects in the collection have completed.
/// </summary>
/// <returns></returns>
public Task WhenAll()
{
_frozen = true;
Task[] tasks;
lock (_lockList)
tasks = _tasks.ToArray();
return Task.WhenAll(tasks)
.ContinueWith(t => { RemoveCompleted(); _frozen = false; });
}
public int Count => _tasks.Count;
/// <summary>
/// Returns count of running tasks.
/// </summary>
public int Running => _tasks.Count(tk => !tk.IsCompleted);
/// <summary>
/// Removes completed tasks from collection.
/// </summary>
public void RemoveCompleted()
{
_tasks = _tasks.Where(tk => !tk.IsCompleted).ToList();
}
/// <summary>
/// Waits until all tasks in collection have completed.
/// </summary>
public void WaitAll()
{
_frozen = true;
RemoveCompleted();
Task[] tasks;
lock (_lockList)
tasks = _tasks.ToArray();
Task.WaitAll(tasks);
RemoveCompleted();
_frozen = false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment