如何确保NSOperations以故障安全方式执行?

时间:2010-08-04 10:52:25

标签: cocoa timeout nsoperation nsoperationqueue

我想要什么

我的应用程序中有一个NSOperationQueue,在应用程序退出之前处理所有操作至关重要。我在quit上有以下代码,以确保在退出前NSOperationQueue为空:

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

在我的代码遇到问题之前,NSOperation在完成之前“冻结”并阻止了整个队列。显然,在这种情况下,我的代码应该抛出一个异常,现在就是这样。

但是我仍然想要防止在操作停止和阻塞队列的任何奇怪事件,导致应用程序永远不会退出并且错误没有被捕获。

我的垃圾解决方案

我正在考虑在队列结束其操作时设置超时。然后,当它超时时,我可以抛出一个异常,然后问题可能会被捕获。

然而,这感觉不对。理想情况下,我不想依赖计时器来确保工作完成。

我的问题

是否有更好的,安全的,确保我的操作没有冻结的方法?

2 个答案:

答案 0 :(得分:4)

如果我理解......

  • 你想知道你的行动还没有结束......变成......
  • 你想知道你的所有操作都将完成......变成......
  • 您要解决the halting problem

祝你好运。

但实际上,你对waitUntilAllOperationsAreFinished的所作所为与你将获得的一样好。您可以添加另一个监视每个操作的类,并确保它不会运行太长时间(比您期望它运行的时间长10倍),此时-cancel NSOperation -isCancelled (或多或少你的计时器方法)。但是,即使这不是万无一失的,因为在无法检查{{1}}的情况下(例如,在系统调用内),可能会阻止操作。

答案 1 :(得分:1)

正如上面的评论中所说的无线电探测器,你实际上并不是在寻找停机问题。如果你可以在操作的长度上做好上限和下限,你可以给每个操作一个时间窗口,看看它们是否已经完成。如果你不能做好下限,那么这就变得效率低下了。此外,如果您的任何操作都有无限循环,他们仍然可能会饿死其他线程,具体取决于您所处的环境。(然后您运气不好。)

使用过于广泛的问题概括来称之为停机问题是计算机科学中的经典错误之一。您并不总是需要一般性问题。请参阅:http://valgrind.org/