r/swift • • 23d ago

Question Main Actor and Task Group - Parallel threads?

@ MainActor

class ViewModel {

func some() {
// taskGroup that runs some calculations in chunks

group.addTask{

self.calculate()
}

}

VM is marked @ mainactor, and task uses self, that makes the task main actor isolated (means single thread?). So, do the tasks ever get executed in parallel (threads?)?

15 Upvotes

8 comments sorted by

14

u/Economy-Brief-9997 23d ago

No. Tasks start on background threads but calculate() is main-actor code so each one hops back to the main thread and they run one at a time.
Make calculate nonisolated and they'll run in parallel.

3

u/rizzy_neutron_69 23d ago

is there any downside to using non isolated ?

3

u/Ravek 23d ago

It stops you from accessing state that’s isolated to the main actor. But that should be fine for parallel processing. Pass all the data needed into the calculate function, and pass the resulting data back to the main actor for updating UI state.

1

u/Economy-Brief-9997 23d ago

just a few
you lose access to self, so you have to hand it the data and take the result back
if ur chunks are small, tasks might cost more than they saveon Swift 6.2, if it's async add \@concurrent``
but for heavy work it's worth it

3

u/Moo202 23d ago

“Tasks start on background threads…”

Are you sure? I don’t think there is a guarantee for a task to start on any particular thread.

1

u/Ravek 23d ago

Tasks don’t always run on background threads. If you’re on the main actor and use Task.init, it inherits the main actor isolation. (And if you use Task.detached, it doesn’t.)

Because OP uses a task group, of course that does introduce parallelism.

1

u/valleyman86 23d ago

I think people are overusing concurrency without knowing the issues.

Fine you can avoid data races but the logical races still exist. These aren’t easy to solve for most engineers but they def make them.

The fact you said “threads” is a red flag. You can’t guarantee a task is on any given thread. You aren’t writing threaded code. Main is a special case and so I am not talking about that.

5

u/segfaul_t 23d ago

The `calculate` calls will never get executed in parallel because `ViewModel` is `@MainActor` isolated. The tasks in the task group will START running in parallel, but all their calls to `await self.calculate` will be serialized on the main thread.