When performing operations that are dependent on each other OperationQueue
could be used to assure they are executed in the correct order. However, would it also be possible to assure that operations are finished one after another?
Let's assume a method that is performed asynchronous and takes some time to finish:
public func performOperation(_ number: Int, success: @escaping (Int) -> Void)->Void {
DispatchQueue(label: "operations").async {
print("Operation #\(number) starts")
usleep(useconds_t(1000-number*200)) // Block thread for some time
success(number)
}
}
The operations and dependencies are created as follows:
let operationQueue = OperationQueue.main
for operationNumber in 0..<4 { // Create operations as an example
let operation = BlockOperation(block: {
performOperation(operationNumber) { number in
DispatchQueue.main.sync {
print("Operation #\(number) finished")
}
}
})
operation.name = "Operation #\(operationNumber)"
if operationNumber > 0 {
operation.addDependency(operationQueue.operations.last!)
// Print dependencies
print("\(operation.name!) should finish after \(operation.dependencies.first!.name!)")
}
operationQueue.addOperation(operation)
}
With the following output:
Operation #1 should finish after Operation #0
Operation #2 should finish after Operation #1
Operation #3 should finish after Operation #2
Operation #0 starts
Operation #1 starts
Operation #2 starts
Operation #3 starts
Operation #0 finished
Operation #3 finished
Operation #2 finished
Operation #1 finished
This is clearly not correct. It seems that OperationQueue
only assures that the operations are started in the right order (instead of finishing one after another).
Although this could be performed using DispatchSemaphore
, I was wondering whether it would also be possible with OperationQueue
.