How to cancel all DispatchQueue operations in Swift?

274 views Asked by At

I am trying to call a method that when called, executes in the background of the global thread of my app. If I call it once, it works fine. If I call the method multiple times, I get weird outputs as the tasks from the previous method calls are still running in the background.

    previousWorkItem?.cancel()
    

    let workItem = DispatchWorkItem {let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
        let dbRef = Database.database().reference().child("shows").child(listingID).child("selectedListing")
        var count = 0
        
        let components = start_time.components(separatedBy: ":")
        let minutes = Int(components[0]) ?? 0
        let seconds = Int(components[1]) ?? 0
        let totalSeconds = minutes * 60 + seconds
        let newMinutes = totalSeconds / 60
        var newSeconds = totalSeconds % 60
        
        if viewer_side {
            newSeconds += 5
        }
        
        print(newSeconds)
        while newSeconds >= 0 {
            sleep(1)
            if newSeconds < 10 {
                dbRef.updateChildValues(["timer": "0\(newMinutes):0\(newSeconds)"]) { error, ref in
                    if let error = error {
                        print("Error updating timer: \(error.localizedDescription)")
                    }
                }
            } else {
                dbRef.updateChildValues(["timer": "0\(newMinutes):\(newSeconds)"]) { error, ref in
                    if let error = error {
                        print("Error updating timer: \(error.localizedDescription)")
                    }
                }
            }
            
            newSeconds -= 1
        }}
    
    
    DispatchQueue.global(qos: .background).async(execute: workItem)
    previousWorkItem = workItem
`

Is there some way I can cancel all the previous processes in the Queue before executing the contents of the method called?

I tried assigning the contents inside the queue to DispatchWorkItem and then cancelling the previous assigned one every time a method was run but, wasn't able to execute the DispatchWorkItem.

1

There are 1 answers

4
vignesh On

Over DispatchQueue the task management can be done by using the DispatchWorkItem like this

import Foundation

var workItem: DispatchWorkItem? = nil

func executeSomeTask(name: String) {
    if workItem != nil {
        workItem?.cancel()
    }
     workItem = DispatchWorkItem {
        // Your task code here
        sleep(10)
        print("Executed the task \(name)")
    }

    workItem?.notify(queue: DispatchQueue.global()) {
        // Cancellation handler code here
        print("Cancelled the task \(name)")
    }
    DispatchQueue.global().async(execute: workItem!)
}

executeSomeTask(name: "1")
executeSomeTask(name: "2")

Out Put:

Cancelled the task 1
Executed the task 2
Cancelled the task 2