Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop execution of a running background thread from main thread on swift while using DispatchQueue

 DispatchQueue.global(qos: .background).async {
    //This will run on the background queue
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(1) )
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(2) )
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(3) )
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(4) )
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(5) )
    // .....
    DispatchQueue.main.async {
        //This will run on the main queue, after the previous code in outer block
        print("done writing data")
    }
}

I need to stop executing this thread from the main thread. How is it possible

like image 726
krishnakumarcn Avatar asked Jan 16 '18 12:01

krishnakumarcn


People also ask

How do you cancel a thread in Swift?

To cancel the operation you'll need to sub-class NSOperation and roll your own. Then you can send use operation. cancel() to cancel an individual operation.

How we can ensure execute code in the main thread?

If you're on a background thread and want to execute code on the main thread, you need to call async() again. This time, however, you do it on DispatchQueue. main , which is the main thread, rather than one of the global quality of service queues.

When use DispatchQueue main Async Swift?

The primary use of DispatchQueue. main. async is when you have code running on a background queue and you need a specific block of code to be executed on the main queue. In your code, viewDidLoad is already running on the main queue so there is little reason to use DispatchQueue.


2 Answers

I think the best solution is to execute DispatchWorkItem in async:

DispatchWorkItem encapsulates work that can be performed. A work item can be dispatched onto a DispatchQueue and within a DispatchGroup

so at the end your code might be:

let workItem = DispatchWorkItem {
   //.... writing stuff in background ....

   DispatchQueue.main.async {
      //.... done writing stuff, updating ui ....
   }
}
DispatchQueue.global().async(execute: workItem)

when you need to stop the execution just call .cancel():

//.... but, if stuff goes wrong ....
DispatchQueue.main.async {
   workItem.cancel()
}
like image 60
Andrea Mugnaini Avatar answered Oct 25 '22 12:10

Andrea Mugnaini


You can use a BlockOperation

let blockOperation = BlockOperation {
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(1) )
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(2) )
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(3) )
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(4) )
    self.writeValue(tag: GlobalData.WRITE_DATA, data: getDataForWrite(5) )
    //...
}

let queue = OperationQueue()
queue.addOperation(blockOperation)

And at some point in time from your main thread you can cancel the operation:

blockOperation.cancel()

More info on BlockOperation

More info on OperationQueue

like image 28
Horatiu Avatar answered Oct 25 '22 11:10

Horatiu