I am running a bunch of items in the background using dispatch_async and sometimes I want to kill what I have in the queue - is this possible? For instance this code is run on a view, and then the user goes back a screen. All of these fired actions keep running regardless of the back navigation. Ideally I would like to kill these items from running:
我使用dispatch_async在后台运行一堆项目,有时我想杀死队列中的内容 - 这可能吗?例如,此代码在视图上运行,然后用户返回屏幕。无论后退导航如何,所有这些已触发的操作都会继续运行。理想情况下,我想从运行中杀死这些项目:
dispatch_async(dispatch_get_global_queue(2, 0), ^{
for (int i=0; i<[self.manufacturers count]; i++) {
NSString *manufacturerID = [[[self.manufacturers objectAtIndex:i] ManufacturerID] stringValue];
[self doSync:manufacturerID withIndex:i setTimer:YES];
}
});
If I create a queue and name it and then release it on the dealloc of the view this is called in they still continue to run.
如果我创建一个队列并命名它,然后在视图的dealloc上释放它,这将被调用,它们仍然继续运行。
2 个解决方案
#1
14
There's no explicit provision in dispatch queues for termination. In order to do this, it is somewhat common to test an escape location to determine termination. Basically, it'd be a semaphore.
调度队列中没有明确规定终止。为此,测试转义位置以确定终止是有点常见的。基本上,它是一个信号量。
NSOperationQueue
(a higher level abstraction, but still build using GCD underneath) does have support for canceling operations. So, for example, you can create a series of NSOperations and add them to an NSOperationQueue and then message -cancelAllOperations
to the queue when you don't need it to complete.
NSOperationQueue(更高级别的抽象,但仍在下面使用GCD构建)确实支持取消操作。因此,例如,您可以创建一系列NSOperations并将它们添加到NSOperationQueue,然后在不需要它完成时将-cancelAllOperations消息发送到队列。
A lot of the architecture you choose will depend on how many of these are operating and whether they have different triggers. Among the implementations, NSOperation is likely the "cleanest" solution, since you have an arbitrary queue which you can watch for operations to be finished on and you can also cancel outstanding operations. Further down the scale of hack would be a volatile location that each of these blocks watch inside of a tight loop to determine if they're going to finish prematurely. Yet further down would be a global variable for the same basic function.
您选择的许多架构将取决于其中有多少架构正在运行以及它们是否具有不同的触发器。在这些实现中,NSOperation可能是“最干净”的解决方案,因为您有一个任意队列,您可以查看要完成的操作,还可以取消未完成的操作。进一步降低黑客的规模将是一个不稳定的位置,每个块都在一个紧密的循环内观察,以确定它们是否会过早完成。然而,对于相同的基本功能,进一步向下将是一个全局变量。
In the end, even the implementation of NSOperation involves a test in order to exit in a consistent location (since just killing a thread might result in inconsistencies in the data being operated upon or in allocations/retrains).
最后,即使NSOperation的实现涉及一个测试,以便在一致的位置退出(因为只是杀死一个线程可能导致在分配/重新训练中操作的数据不一致)。
#2
2
The best way to do this is to create your own concurrent queue (not use one of the global ones) and then call dispatch_suspend() on the queue when you want to stop processing in it. At that point read this: Dispatch queues: How to tell if they're running and how to stop them
执行此操作的最佳方法是创建自己的并发队列(不使用其中一个全局队列),然后在要停止处理队列时调用队列上的dispatch_suspend()。在这一点上阅读:调度队列:如何判断它们是否正在运行以及如何阻止它们
Using a cancellation flag will let you then resume the queue such that all the remaining blocks basically just exit (after doing whatever memory management they need to do, like freeing resources) when you resume it again. You can also dispatch_release() the queue immediately after resuming it.
使用取消标志将允许您恢复队列,以便在您再次恢复时,所有剩余的块基本上都退出(在执行任何需要执行的内存管理之后,如释放资源)。您也可以在恢复后立即调度REPlease()队列。
#1
14
There's no explicit provision in dispatch queues for termination. In order to do this, it is somewhat common to test an escape location to determine termination. Basically, it'd be a semaphore.
调度队列中没有明确规定终止。为此,测试转义位置以确定终止是有点常见的。基本上,它是一个信号量。
NSOperationQueue
(a higher level abstraction, but still build using GCD underneath) does have support for canceling operations. So, for example, you can create a series of NSOperations and add them to an NSOperationQueue and then message -cancelAllOperations
to the queue when you don't need it to complete.
NSOperationQueue(更高级别的抽象,但仍在下面使用GCD构建)确实支持取消操作。因此,例如,您可以创建一系列NSOperations并将它们添加到NSOperationQueue,然后在不需要它完成时将-cancelAllOperations消息发送到队列。
A lot of the architecture you choose will depend on how many of these are operating and whether they have different triggers. Among the implementations, NSOperation is likely the "cleanest" solution, since you have an arbitrary queue which you can watch for operations to be finished on and you can also cancel outstanding operations. Further down the scale of hack would be a volatile location that each of these blocks watch inside of a tight loop to determine if they're going to finish prematurely. Yet further down would be a global variable for the same basic function.
您选择的许多架构将取决于其中有多少架构正在运行以及它们是否具有不同的触发器。在这些实现中,NSOperation可能是“最干净”的解决方案,因为您有一个任意队列,您可以查看要完成的操作,还可以取消未完成的操作。进一步降低黑客的规模将是一个不稳定的位置,每个块都在一个紧密的循环内观察,以确定它们是否会过早完成。然而,对于相同的基本功能,进一步向下将是一个全局变量。
In the end, even the implementation of NSOperation involves a test in order to exit in a consistent location (since just killing a thread might result in inconsistencies in the data being operated upon or in allocations/retrains).
最后,即使NSOperation的实现涉及一个测试,以便在一致的位置退出(因为只是杀死一个线程可能导致在分配/重新训练中操作的数据不一致)。
#2
2
The best way to do this is to create your own concurrent queue (not use one of the global ones) and then call dispatch_suspend() on the queue when you want to stop processing in it. At that point read this: Dispatch queues: How to tell if they're running and how to stop them
执行此操作的最佳方法是创建自己的并发队列(不使用其中一个全局队列),然后在要停止处理队列时调用队列上的dispatch_suspend()。在这一点上阅读:调度队列:如何判断它们是否正在运行以及如何阻止它们
Using a cancellation flag will let you then resume the queue such that all the remaining blocks basically just exit (after doing whatever memory management they need to do, like freeing resources) when you resume it again. You can also dispatch_release() the queue immediately after resuming it.
使用取消标志将允许您恢复队列,以便在您再次恢复时,所有剩余的块基本上都退出(在执行任何需要执行的内存管理之后,如释放资源)。您也可以在恢复后立即调度REPlease()队列。