Допустим, у меня есть коллекция System.Threading.Tasks.Task
:
HashSet<Task> myTasks = new HashSet<Task>();
... и я периодически добавляю в коллекцию больше данных, поскольку у меня появляется больше данных, которые необходимо обработать:
foreach (DataItem item in itemsToProcess)
myTasks.Add(
Task.Factory.StartNew(
() => Process(item),
cancellationToken,
TaskCreationOptions.LongRunning,
TaskScheduler.Default));
Поскольку Task
остаются в состоянии TaskStatus.RanToCompletion
после завершения, а не просто исчезают, они останутся в коллекции до тех пор, пока явно не будут удалены, а коллекция будет расти бесконечно. Чтобы предотвратить это, необходимо сократить задачи Task
.
Один из подходов, который я рассмотрел, - это предоставить Задаче
доступ к коллекции и удалить ее в самом конце. Но я также смотрю на архитектуру, в которой мне пришлось бы удалить задачу, которую не создал мой компонент. Моя первая мысль - прикрепить триггер или событие к завершению каждой Задачи, примерно так:
foreach (Task task in createdSomewhereElse)
{
lock (myTasks) myTasks.Add(task);
task.WhenTaskIsCompleted +=
(o, ea) => { lock(myTasks) myTasks.Remove(task); };
task.Start();
}
... но Задача
не имеет такого события. Есть ли хороший способ выполнить то, что я ищу? Примерно так: