How to cancel one of many streams in swift
Well .. I'm in this situation: I have a function that starts 3 asynchronous threads. Each thread does something that takes some time. When some thread ends up first, I need it to stop the other 2, but I don't know how to do that (yet).
My code:
class SomeController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
threads();
}
func threads(){
let operationQueue = NSOperationQueue();
operationQueue.addOperationWithBlock(
{
let thread = NSThread.currentThread();
let threadNumber = thread.valueForKeyPath("private.seqNum").integerValue;
NSThread.sleepForTimeInterval(30);
println("Task #1 completed on thread #\(threadNumber)");
})
operationQueue.addOperationWithBlock(
{
let thread = NSThread.currentThread();
let threadNumber = thread.valueForKeyPath("private.seqNum").integerValue;
NSThread.sleepForTimeInterval(20);
println("Task #2 completed on thread #\(threadNumber)");
})
operationQueue.addOperationWithBlock(
{
let thread = NSThread.currentThread();
let threadNumber = thread.valueForKeyPath("private.seqNum").integerValue;
NSThread.sleepForTimeInterval(5);
println("Task #3 completed on thread #\(threadNumber)");
})
}}
Any help or quick help would be indicated :)
source to share
This is not a cancellation question NSThread
. Rather, it is a question of how to undo NSOperation
. In this case, it is relatively easy to undo all the operations, since you create one NSOperationQueue
with the sole purpose of executing three blocks. Just send the operationQueue a cancelAllOperations message:
operationQueue.cancelAllOperations()
The unfortunate part is that canceling the operation is indeed joint, so as part of the operation, you should check periodically isCancelled
and complete as needed:
var operation3:NSOperation?
operation3 = operationQueue.addOperationWithBlock {
let thread = NSThread.currentThread()
let threadNumber = thread.valueForKeyPath("private.seqNum").integerValue
var timeout = 5
while timeout-- > 0 && !operation3.isCancelled {
NSThread.sleepForTimeInterval(1)
}
println("Task #3 completed on thread #\(threadNumber)")
operationQueue.cancelAllOperations()
}
source to share
If you create an activity with addOperationWithBlock, you can undo whatever you like, it has no effect. If you want to undo an operation, I recommend not using a block, but subclassing NSOperation. The task being executed must manually check when it is canceled and the task ends; you cannot do it with addOperationWithBlock.
source to share