Создание очереди выполнения с помощью Task.ContinueWith? - PullRequest
6 голосов
/ 21 июля 2011

У меня есть несколько действий, которые я хочу выполнить в фоновом режиме, но они должны выполняться синхронно одно за другим.

Мне было интересно, если это хорошая идея использовать метод Task.ContinueWith для достижения этой цели. Вы предвидите какие-либо проблемы с этим?

Мой код выглядит примерно так:

private object syncRoot =new object();
private Task latestTask;

public void EnqueueAction(System.Action action)
{
    lock (syncRoot)
    {
        if (latestTask == null)
            latestTask = Task.Factory.StartNew(action);
        else
            latestTask = latestTask.ContinueWith(tsk => action());
    }
}

Ответы [ 3 ]

7 голосов
/ 14 июля 2012

В этом есть один недостаток, который я недавно обнаружил сам, потому что я также использую этот метод обеспечения последовательного выполнения задач.

В моем приложении у меня были тысячи экземпляров этих мини-очередей, и я быстро обнаружил, что у меня проблемы с памятью. Поскольку эти очереди часто простаивали, я долгое время держался за последний завершенный объект задачи и предотвращал сборку мусора. Поскольку конечный объект последней выполненной задачи часто превышал 85 000 байт, он был выделен в кучу больших объектов (которая не выполняет сжатие во время сборки мусора). Это привело к фрагментации LOH, и процесс непрерывно увеличивался в размере.

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

5 голосов
/ 21 июля 2011

Это должно работать так, как задумано (используя тот факт, что TPL будет планировать продолжение немедленно, если соответствующая задача уже выполнена).

Лично в этом случае я бы просто использовал выделенный поток, использующий параллельную очередь (ConcurrentQueue) для рисования задач - это более явно, но легче анализировать чтение кода, особенно если вы хотите выяснить, например, сколько задач находится в очереди и т. д.

0 голосов
/ 09 мая 2014

Я использовал этот фрагмент и, похоже, все заработало, как задумано. Количество экземпляров в моем случае исчисляется не тысячами, а одной цифрой. Тем не менее, пока никаких проблем.

Мне было бы интересно узнать пример ConcurrentQueue, если таковой имеется?

Спасибо

...