Как удалить задачу из коллекции после завершения

Допустим, у меня есть коллекция 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();
}

... но Задача не имеет такого события. Есть ли хороший способ выполнить то, что я ищу? Примерно так:

6
задан Calvin Fisher 17 May 2011 в 15:10
поделиться