Swift 并发:调查任务中函数调用触发的上下文变化

问题描述 投票:0回答:1

我很好奇为什么Task CTask D不在主线程上执行,与Task ATask B不同。我理解任务从其父级继承上下文,在这种情况下,它们都共享同一个父级。是否可以假设调用函数会导致创建detached任务?

struct ThreadTestView: View {
    var body: some View {
        Text("Test Thread")
            .onAppear {
                // Task A
                print("Task A - \(threadInfo())")
                
                // Task B
                Task {
                    print("Task B - \(threadInfo())")
                }
                
                // Task C
                printInfo("Task C")
                
                // Task D
                Task {
                    printInfo("Task D")
                }
            }
    }
    
    func printInfo(_ source: String) {
        Task {
            print("\(source) - \(threadInfo())")
        }
        // detached
        Task.detached {
            print("\(source) - detached \(threadInfo())")
        }
    }
    
    func threadInfo() -> String {
        "isMain:\(Thread.isMainThread) - \(Thread.current)"
    }
}

#Preview {
    ThreadTestView()
}

控制台输出:

Task A - isMain:true - <_NSMainThread: 0x280694040>{number = 1, name = main}
Task C - isMain:false - <NSThread: 0x2806c6b00>{number = 8, name = (null)}
Task C - detached isMain:false - <NSThread: 0x2806c4580>{number = 5, name = (null)}
Task B - isMain:true - <_NSMainThread: 0x280694040>{number = 1, name = main}
Task D - isMain:false - <NSThread: 0x2806c6b00>{number = 8, name = (null)}
Task D - detached isMain:false - <NSThread: 0x2806c6b00>{number = 8, name = (null)}
swift swiftui async-await concurrency task
1个回答
0
投票

巨大的免责声明:我仍在填补自己对 Swift Concurrency 理解的空白,因此我很高兴以下任何陈述被证明是错误的。

我认为这里重要的一点是“主线”与“主角”不是一回事。两者之间存在一些差异,但一个显着的差异是参与者是一种编译时构造,而线程主要是一种运行时构造。仅仅因为代码在主线程上运行并不意味着它是“主要参与者隔离的”。查看 onAppear(perform:) 方法的文档,您可以看到

perform
闭包不包含
@MainActor
注释,因此它不是主要参与者隔离的,尽管我们可以非常有信心它将在主线程上调用。因此,当您从该闭包内部实例化
Task
时(尽管
Task.init
继承了当前 actor),闭包本身并不是与 actor 隔离的,因此没有可以继承的 actor。执行器可以自由地将此任务安排在协作线程池中可用的任何线程上,甚至可以安排在主线程上。尝试用
printInfo
注释您的
@MainActor
函数,看看情况如何变化。

© www.soinside.com 2019 - 2024. All rights reserved.