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 :)

+3


source to share


2 answers


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()
}

      

+3


source


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.



+1


source







All Articles