代码之家  ›  专栏  ›  技术社区  ›  John Gallagher

如何确保nsoperations以故障保护方式执行?

  •  2
  • John Gallagher  · 技术社区  · 15 年前

    我想要什么

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

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

    我以前遇到过我的代码问题,在完成前一个nsOperation“冻结”,它阻塞了整个队列。显然,在这样的情况下,我的代码应该抛出一个异常,它现在已经抛出了。

    但我仍然想防止在操作停止并阻塞队列时发生任何奇怪的事情,从而导致应用程序永远不会退出,并且故障不会被捕获。

    我的垃圾解决方案

    我正在考虑将队列超时,以完成其操作。然后当它超时时,我可以抛出一个异常,然后问题就可以被捕获了。

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

    我的问题

    有没有更好的,故障安全的方法,以确保我的操作没有冻结?

    2 回复  |  直到 13 年前
        1
  •  4
  •   Dave DeLong    15 年前

    如果我明白…

    • 你想知道你的业务还没有冻结…变成…
    • 您想知道您的所有操作都将完成执行…变成…
    • 你想解决 the halting problem

    祝你好运。

    但实际上,你在做什么 waitUntilAllOperationsAreFinished 差不多是你能得到的。您可以添加另一个类来监视每个操作,并确保它不会运行太长时间(比如说比预期运行时间长10倍),此时它将 -cancel 这个 NSOperation (或多或少你的计时器方法)。然而,即使这样也不是万无一失的,因为在你无法检查的地方操作可能会被阻塞。 -isCancelled (例如,在系统调用中)。

        2
  •  1
  •   StCredZero    13 年前

    正如RadioPiel在上面的评论中所说,实际上你并不是在寻找停止的问题。如果您可以在操作的长度上进行良好的上下限操作,那么您可以给每个操作一个时间窗口,并查看它们是否完成。如果你不能很好的下界,那么这就变得低效了。另外,如果您的任何操作有一个无限循环,它们仍然会使其他线程挨饿,这取决于您所处的环境。(然后你就走运了。)

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