Last active
December 26, 2021 13:10
-
-
Save jamescurran/46d90e84646c3c308cdea0d664addd1d to your computer and use it in GitHub Desktop.
Code for blog article https://honestillusion.com/2021/12/17/TaskCollection.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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