Как я могу убедиться, что NSOperations выполняется безотказно? - PullRequest
2 голосов
/ 04 августа 2010

Что я хочу

У меня в приложении есть NSOperationQueue, и очень важно, чтобы все операции были обработаны до его закрытия. У меня есть следующий код при выходе, чтобы убедиться, что NSOperationQueue пуст перед выходом:

if ([NSThread isMainThread]) {
    while ([[operationQueue operations] count] > 0) {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.05]];
    }
} else {
    [operationQueue waitUntilAllOperationsAreFinished];
}

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

Но я все еще хочу защититься от всего странного, когда операции останавливаются и блокируют очередь, в результате чего приложение никогда не завершает работу и ошибка не обнаруживается.

Мое решение для мусора

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

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

Мой вопрос

Есть ли лучший, надежный, способ убедиться, что мои операции не заморожены?

Ответы [ 2 ]

4 голосов
/ 04 августа 2010

Если я понимаю ...

  • вы хотите знать, что ваши операции не заморожены ... становится ...
  • вы хотите знать, что все вашиоперации завершатся ... становится ...
  • вы хотите решить проблема остановки

Удачи с этим.

Реально, однако, то, что вы делаете с waitUntilAllOperationsAreFinished, примерно так же хорошо, как вы собираетесь получить.Вы можете добавить другой класс, который будет наблюдать за каждой операцией и следить за тем, чтобы она не выполнялась слишком долго (скажем, в 10 раз дольше, чем вы ожидаете, что она будет выполняться), после чего она будет -cancel NSOperation (более или менеетвой таймер подойдет).Однако даже это не является надежным, потому что операция может быть заблокирована для чего-то, что вы не можете проверить на -isCancelled (например, внутри системного вызова).

1 голос
/ 06 июня 2012

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

Использование слишком широких обобщений проблемназывать их «проблема остановки» - одна из классических ошибок информатики.Вам не всегда нужна общая проблема.Смотри: http://valgrind.org/

...