Приостановка и приостановка задач GCD [дублировать]

Конечно, есть много таких подходов, как синхронный запрос, обещание, но из моего опыта я думаю, что вы должны использовать подход обратного вызова. Естественно, что асинхронное поведение Javascript. Итак, ваш фрагмент кода можно переписать немного иначе:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            myCallback(response);
        }
    });

    return result;
}

function myCallback(response) {
    // Does something.
}
21
задан lakshmanbob 8 April 2015 в 10:06
поделиться

2 ответа

Чтобы приостановить очередь отправки, это просто dispatch_suspend(queue) в Objective-C или Swift 2.3 или queue.suspend() в Swift 3. Это не влияет на какие-либо запущенные в данный момент задачи, а просто предотвращает запуск новых задач в этой очереди , Кроме того, вы, очевидно, только приостанавливаете очереди, которые вы создали (а не глобальные очереди, а не главную очередь).

Чтобы возобновить очередь отправки, это dispatch_resume(queue) в Objective-C или Swift 2.3 или queue.resume() в Swift 3. Нет понятия «авто возобновление», поэтому вам просто нужно вручную возобновить его, когда это необходимо.

Чтобы передать очередь отправки, вы просто передаете объект dispatch_queue_t, который вы создали когда вы вызывали dispatch_queue_create() в Objective-C или Swift 2.3, или в Swift 3, объект DispatchQueue, который вы создаете с помощью DispatchQueue(label:) .

С точки зрения отмены задачи, поставленные в очередь на очереди отправки, это новая функция iOS 8, и вы вызываете dispatch_block_cancel(block) с вашим объектом dispatch_block_t в Objective-C или Swift 2.3 или item.cancel() в DispatchWorkItem в Swift 3. Это отменяет блоки / элементы в очереди, которые еще не запущены, но не останавливают выполняемые. Если вы хотите прервать отправленный блок / элемент, вам необходимо периодически проверять dispatch_block_testcancel() в Objective-C и Swift 2.3 или item.isCancelled в Swift 3.

Отмена блоков GCD достаточно сложна, чтобы я мог ссылаться на видео WWDC 2014 Power, Performance и Diagnostics: что нового в GCD и XPC , в котором представлена ​​информация о вас к концепции объектов блока отправки, их очереди, их отмены и т. д. Хотя это описывает более старый API Objective-C и Swift 2.3, все концепции в равной степени применимы к новому API Swift 3.

Если вы хотите отменить задачи, вы можете также рассмотреть возможность использования очередей операций NSOperationQueue в Objective-C или Swift 2.3, ака OperationQueue в Swift 3, поскольку его отменяемые операции были вокруг в то время как вы, вероятно, найдете множество примеров в Интернете. Он также поддерживает ограничение степени параллелизма с maxConcurrentOperationCount (тогда как с диспетчерскими очередями вы можете выбирать только между последовательными и параллельными и управлять параллелизмом больше, чем требует крошечных усилий с вашей стороны).

При использовании очередей операций вы приостанавливаете и возобновляете, изменяя свойство suspended очереди. И чтобы передать это, вы просто передаете объект NSOperationQueue, который вы создали.


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


В ваших комментариях вы упомянете, что вы использовали NSTimer, aka Timer в Swift 3. Если вы хотите остановить таймер, вызовите timer.invalidate() , чтобы остановить его. Создайте новый NSTimer, когда вы хотите запустить его снова.

Или, если таймер действительно работает в фоновом потоке, таймеры GCD делают это намного более изящно, избегая глупости необходимости создания runloop на фоновом потоке, который вам нужно запустить NSTimer в фоновом потоке. С помощью таймера GCD вы можете приостановить / возобновить его, как если бы вы приостановили / возобновили очередь, просто используя объект таймера вместо объекта очереди.

46
ответ дан Rob 28 August 2018 в 22:40
поделиться

Вы не можете приостанавливать / отменять при использовании очереди GCD. Если вам нужна эта функциональность (и во многих общих случаях, даже если вы этого не сделаете), вы должны использовать API более высокого уровня - NSOperationQueue. Это построено поверх GCD, но оно дает вам возможность контролировать, сколько вещей выполняется одновременно, приостанавливать обработку очереди и отменять отдельные / все операции.

3
ответ дан Wain 28 August 2018 в 22:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: