Now that we have the new concurrency features in Swift 5.5, I'm wondering what the best way is to perform a small bit of work on the main actor from an asynchronous function. I know I can create a dedicated function and decorate it with @MainActor, but sometimes the work is too trivial to get a named function.
That’ll suspend the calling function and resume it once the main actor is done which mightn’t be necessary/possibly wasteful. What if you just simply want to “fire and forget” some work off to the Main actor?
Hi @ktoso, I recently learned about the Task { @MainActor in hello() } syntax and I'm wondering why you suggest the alternative (the // or better bit) instead?
Is it because a Task can call out to functions on various actors without needing to define everything as occurring on the main actor? What happens if you mark the Task with @MainActor like that but then call out to function on another actor?
I find it hard to build a strong intuition about all this, especially because (from my understanding) the code of two actors may even be running on the same thread (?)
No. No actors ever use the same thread concurrently, that’s not a thing. They may (not the main one) use some concrete thread one after another tho… it is best to not really think about threads but just executors instead.
Yes thanks for clarifying. I didn't mean the code from two actors running concurrently on the same thread, but potentially serially, from what I understand.
So from what I can tell the main reason you're suggesting against Task { @MainActor in would be to potentially reduce hops if you also want to call into non-MainActor async code within that Task. Am I understanding that correctly?
If you're spawning a task to immediately call other actor methods yeah, I'd suggest not instructing the task to be run on any specific actor, since that'd needlessly hop to that one, and then off from it again.