Можно ли ждать выполнения неизвестных задач? - PullRequest
3 голосов
/ 24 августа 2011

Используя .NET Task Parallel Library, есть ли встроенный способ ожидания завершения всех запущенных Задач без фактической ссылки на Задачи?

Task.WaitAny() и Task.WaitAll() обатребуется массив Task экземпляров.Что-то, что я хотел бы, это что-то вроде Task.WaitAll(), которое не принимает аргументов и просто ждет завершения всех задач, порожденных моим приложением.

Если нет, я что-то встроу в мою среду, ноЯ не хочу изобретать велосипед, если смогу помочь.

Ответы [ 2 ]

5 голосов
/ 24 августа 2011

Я знаю, что это не отвечает на ваш вопрос напрямую, но вы можете изменить свою архитектуру, чтобы все задачи создавались как дочерние элементы одной "основной" задачи.Ожидание этой «главной» задачи затем автоматически ожидает всех ее дочерних элементов.

Вы можете создать дочернюю задачу следующим образом:

Task.Factory.StartNew(
    () => /* ... */,
    TaskCreationOptions.AttachedToParent
);

Следующие ссылки могут оказаться полезными, когда она появитсяна тему дочерних задач:

4 голосов
/ 25 августа 2011

Поскольку любой Task может порождаться любым кодом .NET (например, BCL, некоторой библиотекой и т. Д.), Вы, вероятно, не хотите ждать выполнения всех задач, которые ожидают выполнения, а только тех, которые есть в вашем собственном коде. создано. Самый простой способ - создать собственную фабрику, которая использует базовую фабрику, которая отслеживает все незавершенные задачи и предоставляет нужные функции ожидания

public class MyTaskFactory {
    private HashSet<Task> _tasks = new HashSet<Task>();

    public Task<T> StartNew<T>(Func<T> func) {
        var t = Task.Factory.StartNew(func);
        t.ContinueWith(x => {
          lock(_tasks) {
            _tasks.Remove(x);
          }
        });
        lock(_tasks) {
          _tasks.Add(t);
        }
        return t;
    }

    // ... implement other StartNew overrides ...

    public void WaitAll() {
        Task[] tasks;
        lock(_tasks) {
          tasks = _tasks.ToArray();
        }
        Task.WaitAll(tasks);
    }
}
...