'swift async function is being run on the main thread in some cases when run from task
In this case the async function reads a file and returns the parsed contents.
In my view I want to load the contents off of the main thread, and then update the view once complete.
I've used this pattern in various places and noticed that in some cases the async call is on the main thread (by debugging) while in others it is on the Thread 4 Queue : com.apple.root.user-initiated-qos.cooperative (concurrent) thread
For example:
struct MyView: View {
@State var data = "some data"
var body: some View {
Button("refresh") {
// when the button is pressed refresh it
Task {
await refresh()
}
}.task {
// when the view appears
await refresh()
}
Text("the data is \(data)") // write the data which was refreshed async
}
}
func refresh() async {
do {
let res = try await anotherAyncFunction()
data = res // this is presumably wrong and off the main thread - obviously might not be correct but leave here for debug as well
} catch {
print("got error \(error)")
}
}
I created several different views using a similar pattern (.task block calling async functions)
In some cases the functions are long running (reading from disk) and that is happening on the main thread
Solution 1:[1]
Change Task { to Task.detached {.
From the Swift Language Guide:
To create an unstructured task that runs on the current actor, call the
Task.init(priority:operation:)initializer. To create an unstructured task that’s not part of the current actor, known more specifically as a detached task, call theTask.detached(priority:operation:)class method.
When you call Task.init, the asynchronous code runs on the current actor, which, in this context is the main actor. This has the result of blocking the main thread.
By calling Task.detached, you allow the asynchronous work to happen off the main thread.
Solution 2:[2]
Using Swift structured concurrency, to run code on a background thread, use a detached task or (better) an actor.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | John M. |
| Solution 2 | matt |
