0

Is there a way to stop a concurrentPerform operation?

let count = arr.count
let group = DispatchGroup()
group.enter()
DispatchQueue.concurrentPerform(iterations: count, execute: { i in
    if stop { group.leave(); return }  // Crashes with EXC_BAD_INSTRUCTION
    // ..
})
group.wait()

This crashes with EXC_BAD_INSTRUCTION after a few iteration. Seems like the group.leave() is not exiting the operation. How to exit cancel the operation? Basically, what I am trying to do is loop an array concurrently and break out of it if some condition is met, without using Objective-C bridge to use concurrent enumeration.

John Doe
  • 2,225
  • 6
  • 16
  • 44
  • 1
    You probably should not create a work item for each array element, but work on “strides.” See for example https://stackoverflow.com/a/39949292/1187415 where a work item is created for every row of a grid. (Actually all of [Rob's answers about this topic](https://stackoverflow.com/search?q=user%3A1271826+concurrentperform) are worth reading :) – Martin R Jun 04 '19 at 18:50
  • doh! I placed the bounty accidentally on the wrong question. I had meant to do so here: https://stackoverflow.com/questions/75459511/writing-to-different-swift-array-indexes-from-different-threads/75460107 – johnbakers Feb 16 '23 at 19:26

1 Answers1

2

DispatchQueue.concurrentPerform causes the block to be executed the specified number of times, and waits for all iterations to complete. There is no way to prevent that. (The blocks run in parallel if the target queue is a concurrent queue.)

Of course each work item can “early return” if some condition is met, but that won't affect the other work items.

Your code crashes because leave() is called on the dispatch group more times than enter().

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Since `concurrentPerform` is a type method and not called on a specific instance/reference to a particular queue, then what exactly does "The blocks run in parallel if the target queue is a concurrent queue." mean? There is no API to specify what the target queue is, is there? What would be a scenario when it was *not* run concurrently on multiple threads? – johnbakers Feb 16 '23 at 11:14
  • @johnbakers: Yes, that is a strange API. See https://stackoverflow.com/a/39949292/1187415 for an example: You call concurrentPerform inside an async block of a concurrent queue. – Martin R Feb 16 '23 at 12:12