是否可以在执行期间终止长时间运行的任务?

时间:2017-09-20 11:14:25

标签: ios asynchronous grand-central-dispatch nsthread cancellation

我有一个预建的C库(二进制文件和标题),其中包含一个重函数。此功能可能需要一分钟或更长时间才能完成。通常我使用GCD在后台移动计算并保持UI线程免费:

// show activity indicator or something else

dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
dispatch_async(queue, ^{
    void *resultData = callOfHeavyLibraryMethodHere(params);
    dispatch_async(dispatch_get_main_queue(), ^{
        // show resultData to user
    });
});

但是如果用户想要取消此操作呢?据我所知,我无法阻止GCD中的阻止。我读到了NSThread - 但它也无法从其他线程(main)中删除一个线程(带有计算)。还有其他解决方案吗?

我无法使用此回答How to cancel/exit/stop execution of Thread object or thread running in background in IOS中的解决方案,因为即使我调用cancel方法,我也无法检查isCancelled变量。

这不是我的情况:

NSOperationQueue* myQueue = [[NSOperationQueue alloc] init];
NSBlockOperation* myOp = [[NSBlockOperation alloc] init];

[myOp addExecutionBlock:^{
    for (int i = 0; i < 1000000; i++)
    {
        if ([myOp isCancelled]) // <-- check and interrupt operation
            return;
        doSmallPartOfWorkForItemAtIndex(i);
    }
}];
[myQueue addOperation:myOp];

这是我的理由:

NSOperationQueue* myQueue = [[NSOperationQueue alloc] init];
NSBlockOperation* myOp = [[NSBlockOperation alloc] init];

[myOp addExecutionBlock:^{
    void *resultData = callOfHeavyLibraryMethodHere(params);
    // pass data somewhere else
}];
[myQueue addOperation:myOp];

无法检查isCancelled,操作不会以这种方式中断。此外,我也无法调用[NSThread exit],因为我的代码中没有中间点。

1 个答案:

答案 0 :(得分:0)

调度队列的问题在于,一旦发送任务,您就无法取消任务。但是,您可以使用NSOperationQueue代替

NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
    void *resultData = callOfHeavyLibraryMethodHere(params);
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // Main thread work (UI usually)
    }];
}];

NSOperationQueue *queue = [NSOperationQueue new];
[queue addOperation:operation];
// you can cancel an operation like so
[operation cancel];

取消任务的能力是NSOperationQueue优于GCD的一个优势。另一个是在操作之间添加依赖关系的可能性,它可以非常方便。