首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >GCD:如何从串行队列中移除等待的任务?

GCD:如何从串行队列中移除等待的任务?
EN

Stack Overflow用户
提问于 2012-09-07 19:24:13
回答 3查看 9K关注 0票数 12

首先,我创建一个串行队列,如下所示

代码语言:javascript
运行
复制
static dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);

然后,在某个未知的时间点,任务被添加到队列中,如下所示

代码语言:javascript
运行
复制
dispatch_async(queue, ^{
    // do something, which takes some time
});

如果第一个任务尚未完成,则新任务将等待第一个任务完成(这当然是串行队列的作用)。

但是如果我在队列中添加了5个新任务,而原来的第一个任务还在运行,我不想执行新的1号任务,然后是2号任务,然后是3号任务,而是想要摆脱任务1到4,在原来的第一个任务完成后直接开始执行任务5。

换句话说,如果我添加了一个新的任务,我希望将任何等待的任务(不是当前正在运行的任务)从队列中弹出。

有没有内置的机制,或者我必须自己实现它?对于后者,我如何识别队列中的单个任务并删除它们?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-09-07 22:39:45

一旦一个块被提交到GCD分派队列,它就会运行。没有办法取消它。正如您所知道的,您可以实现自己的机制来提前“中止”块执行。

一种更简单的方法是使用NSOperationQueue,因为它已经提供了取消挂起操作(即那些尚未运行的操作)的实现,并且您可以使用新的addOperationWithBlock方法轻松地将块排队。

虽然NSOperationQueue是使用GCD实现的,但我发现GCD在大多数情况下更容易使用。然而,在这种情况下,我会认真考虑使用NSOperationQueue,因为它已经处理了取消挂起的操作。

票数 18
EN

Stack Overflow用户

发布于 2012-09-07 20:26:53

有了Davids answer让我走上正轨,我成功地这样做了

代码语言:javascript
运行
复制
taskCounter++;
dispatch_async(queue, ^{
    if (taskCounter > 1) {
        taskCounter--;
        NSLog(@"%@", @"skip");
        return;
    }
    NSLog(@"%@", @"start");
    // do stuff
    sleep(3);
    taskCounter--;
    NSLog(@"%@", @"done");
});

taskCounter必须是一个ivar或一个属性(用0初始化)。在这种情况下,它甚至不需要__block属性。

票数 5
EN

Stack Overflow用户

发布于 2012-09-07 19:28:15

处理这种情况的方法是使用ivar,它向排队的块指示它们应该只返回:

代码语言:javascript
运行
复制
^{
  if(!canceled) {
    ... do work
  }
}

你也不需要使用简单的布尔值--你可以让它变得更复杂--但一般的想法是在做任何事情之前使用一个或多个ivars来查询块。

我使用这种技术(但不是我发明的)取得了巨大的成功。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12317154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档