In this sample:
func isMainThread() -> Bool {
return Thread.isMainThread
}
let task = Task.detached {
await withTaskCancellationHandler(
operation: { @MainActor in
print("operation() started -> isMainActor: \(isMainThread()), thread: \(pthread_self())")
try? await Task.sleep(for: .seconds(2))
print("operation() finished -> isMainActor: \(isMainThread()), thread: \(pthread_self())")
},
onCancel: {
print("onCancel() -> isMainActor: \(isMainThread()), thread: \(pthread_self())")
},
isolation: MainActor.shared
)
}
await Task.detached {
try? await Task.sleep(for: .seconds(1))
print("cancel() -> isMainActor: \(isMainThread()), thread: \(pthread_self())")
task.cancel()
}.value
I get this output:
operation() started -> isMainActor: true, thread: 0x202e105c0
cancel() -> isMainActor: false, thread: 0x16fe87000
onCancel() -> isMainActor: false, thread: 0x16fe87000
operation() finished -> isMainActor: true, thread: 0x202e105c0
Which makes sense: the Main Actor can't execute both operation and onCancel concurrently.
You can also see that cancel() and onCancel happen on the same thread.