0

在我的应用程序中,我在后台运行服务器。我正在使用 aNSOperation这样做。(我之前用过 GCD 但我需要能够停止它,所以我切换到NSOperation,但我仍然不知道如何。)

所以本质上,我的NSOperation子类看起来像这样:

- (void)main {
    server_main(var1, var2);
}

由于这是一个服务器,该server_main函数基本不返回。我也无法控制该功能的实现。

有时,用户会更改服务器的设置。发生这种情况时,我想停止然后重新启动服务器。if (self.isCancelled)如果我理解正确,我需要在子类中做类似的事情NSOperation,但由于它会卡在server_main函数中,我怀疑它是否真的有效。

那么如何停止服务器呢?

非常感谢!

4

3 回答 3

2

要正确地做到这一点,请参阅并发编程指南中的响应取消事件,其中说:

尽管NSOperation该类为客户提供了一种取消操作的方法,但识别取消事件是必要的。如果操作完全终止,则可能无法回收已分配的资源。因此,操作对象应该检查取消事件,并在它们发生在操作中间时优雅地退出。

要在操作对象中支持取消,您所要做的就是isCancelled从您的自定义代码中定期调用该对象的方法,并在它返回时立即返回YES

这是一种冗长的说法,我真的认为你需要能够改变server_main,以便它:

  • isCancelled定期检查,或

  • 让它提供一个回调/进度委托方法块,这样你就可以自己做,也可以调用一些额外的函数/方法来取消server_main,让它进入关键的清理过程。

如果您只是开始杀死进程(如果可以的话),您无疑会泄漏资源或使其server_main处于不一致的状态。

我知道这不是您要寻找的答案,但这是取消操作的方式。对不起。

于 2013-05-01T13:02:34.363 回答
0

你可以使用

- (void)setSuspended:(BOOL)suspend

NSOperationQueue 上的方法?并且在添加新操作之前,使用 isSuspended 检查队列是否被挂起?

编辑:这里参数挂起 如果是,队列停止调度排队的操作以供执行。如果否,则队列再次开始调度操作。讨论 此方法暂停或恢复操作的执行。暂停队列可防止该队列启动其他操作。换句话说,队列中(或稍后添加到队列中)且尚未执行的操作将被阻止启动,直到队列恢复。暂停队列不会停止已经在运行的操作。

只有当它们完成执行时,操作才会从队列中移除。但是,为了完成执行,必须首先启动一个操作。因为挂起的队列不会启动任何新操作,所以它不会删除当前排队且未执行的任何操作(包括已取消的操作)。

希望它可以帮助你。

于 2013-05-01T12:12:55.320 回答
0

你可以试试这段代码:

@interface Canceller
{
    BOOL _shouldCancel;
}
- (void)setShouldCancel:(BOOL)shouldCancel;
- (BOOL)shouldCancel;
@end

@implementation Canceller
- (void)setShouldCancel:(BOOL)shouldCancel {
    _shouldCancel = shouldCancel;
}
- (BOOL)shouldCancel {
    return _shouldCancel;
}
@end

static void test(int a){
    static Canceller * canceller = nil;

    if(q){
        [canceller setShouldCancel:YES];
        [canceller release];
        dispatch_suspend(q);
        dispatch_release(q);
        q=nil;
    }
    canceller = [[Canceller alloc] init];
    q=dispatch_get_global_queue(0,0);
    dispatch_async(q,^ {
        while(![canceller shouldCancel]){NSLog(@"query %d",a);sleep(2);}
    });

}

希望能帮助到你。

于 2013-05-01T12:33:59.183 回答