В финальной точке я хочу «Подождать все» невыполненные задачи, прежде чем продолжить другой код.
Это все, что я хочу. И я ищу готовый шаблон для этого!
" while (..) { Task.Start(); Tasks.Add(task); } Task.WaitAll(tasks);" (выполненная задача самостоятельно удаляется из задач)
Это мой первый пост с вопросом по «stackoverflow» — прошу прощения, если что-то не так
Код: Выделить всё
// TaksBag some “global” variable for Task concurrent collection as “ConcurrentDictionary()” - I don’t know another standard solution for this
//some cycling code begin
Task tsk = null;
tsk = new Task(() => { var t = tsk; TasksBag.TryAdd(t, 0); SomeProcess(); TasksBag.TryRemove(t, out _); }); //Many “times” (points) in code
tsk.Start();
//Perhaps this realization is better begin
Task tsk = new Task(() => SomeProcess ());
TasksBag.TryAdd(tsk, 0);
tsk.ContinueWith((t) => TasksBag.TryRemove(t, out _), TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.OnlyOnRanToCompletion);
tsk.Start();
//Perhaps this realization is better begin
//some cycling code end
//Final point
var ta = TasksBag.Keys.ToArray();
Task.WaitAll(ta);
//TasksBag.TryRemove() //not needed
Могут быть две различные архитектурные ситуации в Финальной точке:
- Новые задачи в коллекцию не добавляются. И эта точка наступает только один раз
или - Новые задачи можно продолжать добавлять в коллекцию, но на этом этапе их следует исключить из коллекции. Возможно, позже в этом месте еще будет новый хит и следующая обработка "WaitAll"
Обновление №1:
Подумав, я решаю — эту проблему нельзя оставлять без обработки исключений. И это усложняет проблему после «WaitAll». Задачи, "не дошедшие до конца", останутся в коллекции задач из-за исключения (но, судя по всему, не в версии с "ContinueWith", но это хитро - исключение может произойти внутри "ContinueWith" без удаления задачи из коллекции). коллекция; "еще один вопрос" - изменится ли что-то при обработке исключений в "Конечной точке" - это рассматривать не буду) - и выполненная (неудачная) задача не удалит себя из коллекции задач!
Код: Выделить всё
var ta = TasksBag.Keys.ToArray();
Task.WaitAll(ta);
foreach (var tsk in ta)
TasksBag.TryRemove(tsk, out _); //no exception processing for simplify; not needed if only hit once to this point (GC or app exit solve this)
Обновление №2. Это настоящая моя проблема:
Я анализирую веб-адреса. И я хочу создать каждую задачу для обработки каждого из них. Но я задал вопрос - найти общепринятую закономерность решения проблемы ожидания еще невыполненных задач (после выхода из блока их генерации). Когда процесс может сгенерировать колоссальное количество (коротких) задач до того, как будет выполнено «WaitAll»!
Подробнее здесь: https://stackoverflow.com/questions/792 ... ent-in-net
Мобильная версия