Допустим, у меня есть коллекция 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
s остаются в состоянии TaskStatus.RanToCompletion
после завершения, а не просто исчезают, они будут оставаться в коллекции до тех пор, пока не будут явно удалены, и коллекция будет расти бесконечно.Чтобы предотвратить это, нужно Task
обрезать.
Один из подходов, которые я рассмотрел, - это дать Task
доступ к коллекции и удалить ее в самом конце.Но я также смотрю на архитектуру, где мне пришлось бы удалить задачу, которую мой компонент не создал.Моя первая мысль - прикрепить триггер или событие к завершению каждой Задачи, что-то вроде этого:
foreach (Task task in createdSomewhereElse)
{
lock (myTasks) myTasks.Add(task);
task.WhenTaskIsCompleted +=
(o, ea) => { lock(myTasks) myTasks.Remove(task); };
task.Start();
}
... но Task
не имеет такого события.Есть ли хороший способ выполнить то, что я ищу?Примерно так: