我明白,演员体内的所有并行工作不知何故都会变成连续剧,这是某种同步过程的一部分.我们可以看到,应该并行完成的async let个工作在Actor1中是按顺序完成的,这很可能是由于参与者的内部同步.但是,尽管AnActor内部同步,但withTaskGroup-工作并行运行,但为什么?)

编辑:同时,我想说,当使用await从参与者的内部外部调用时,我理解同步是如何工作的,但我不理解同步是如何在参与者内部工作的,以调用参与者内部的异步并行任务.

import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView().task {
                //await AnActor().performAsyncTasks() // uncomment this alternately and run
                //await Actor1().performAsyncTasks() // uncomment this alternately  and run
            }
        }
    }
}

actor Actor1 {
    
    func performAsyncTasks() async {
        async let _ = asyncTasks1() // this not running in parallel
        async let _ = asyncTasks2() // this not running in parallel
    }
    
    func asyncTasks1() async {
        for i in 1...10_000_0 {
            print("In Task 1: \(i)")
        }
    }
    
    func asyncTasks2() async {
        for i in 1...10_000_0 {
            print("In Task 2: \(i)")
        }
    }
}  // the printed text are in series with Task 1 and Task 2 in console

actor AnActor {
    var value = 0

    func performAsyncTasks() async {
        value = await withTaskGroup(of: Int.self) { group in
            group.addTask { // this running in parallel, why?!
                var value1 = 0
                for _ in 1...10_000 {
                    print("Task1")
                    value1 += 1
                }
                return value1
            }

            group.addTask { // this running in parallel, why?!
                var value2 = 0
                for _ in 1...10_000 {
                    value2 += 1
                    print("Task2")
                }
                return value2
            }

            return await group.reduce(0, +)
        }

        print(value)
    }
}  // the printed text are mixed with Task 1 and Task 2 in console

推荐答案

考虑您的第一个示例:

actor Actor1 {
    func performAsyncTasks() async {
        async let _ = asyncTasks1() // this not running in parallel
        async let _ = asyncTasks2() // this not running in parallel
    }
    
    func asyncTasks1() async {
        for i in 1...10_000_0 {
            print("In Task 1: \(i)")
        }
    }
    
    func asyncTasks2() async {
        for i in 1...10_000_0 {
            print("In Task 2: \(i)")
        }
    }
}

你说过:

我们可以看到,应该并行完成的async let个工作是在Actor1中按顺序完成的

是的,通常async let可以让 routine 并发运行.但这不会在这里发生,因为这两个功能都独立于同一个参与者,并且没有await个停止点.


有人说:

如果async letlet _ = await asyncTasks1()…的缩写

但事实并非如此.请参见SE-0317.

如果你想看到并行执行,你可以使用async let.您只需要使用非隔离函数:

actor Foo {
    func performAsyncTasks() async {
        async let value1 = asyncTasks1() // this IS running in parallel
        async let value2 = asyncTasks2() // this IS running in parallel
        let total = await value1 + value2
        print(total)
    }

    nonisolated func asyncTasks1() async -> Int {
        await poi.interval(name: #function) {
            var value = 0
            for _ in 1...1_000_000_000 {
                value += 1
            }
            return value
        }
    }

    nonisolated func asyncTasks2() async -> Int {
        await poi.interval(name: #function) {
            var value = 0
            for _ in 1...1_000_000_000 {
                value += 1
            }
            return value
        }
    }
}

如果我在仪器中分析它,我可以看到它们是并行运行的:

enter image description here

顺便说一句,上面使用了以下POI实用程序函数:

import os.log

let poi = OSLog(subsystem: "Test", category: .pointsOfInterest)

extension OSLog {
    func interval<T: Sendable>(name: StaticString, block: () async throws -> T) async rethrows -> T {
        let id = OSSignpostID(log: self)
        os_signpost(.begin, log: self, name: name, signpostID: id)
        defer { os_signpost(.end, log: self, name: name, signpostID: id) }
        return try await block()
    }
}

Ios相关问答推荐

如何将模糊输入/模糊输出添加到SwiftUI中的非对称过渡?

无法下载并安装带有Xcode 15.0的iOS 17.0模拟器运行时

清除/删除 NavigationController 中的多个 ViewController

swiftui 图像放大时无法正确拖动

Apple Metal iOS 为什么 GLKMatrix4MakeLookAt 来回摇摆

Swift:判断 Foundation (NS)Errors 与自定义协议的一致性

Flutter动画放大图

Flutter firebase_auth 中的无效应用程序凭据/令牌不匹配

在 Swift 中使用 UITesting 捕获屏幕录像

Xcode 14 需要为 Pod Bundles Select 开发团队

我们可以在 Swift 中将 struct 中的 Codable 键设置为不区分大小写吗

为什么我的应用在 Testflight 中没有下载 dSYM 按钮?

如何在通用应用程序中同时支持 iPad 和 iPhone 视网膜图形

如何使用 sendAsynchronousRequest:queue:completionHandler:

在 iOS 8 中显示相机权限对话框

没有 Mac 的 Xamarin Visual Studio IOS 开发?

如何像在 Facebook 应用程序中一样以编程方式打开设置?

iOS中的apk类似功能是什么?

Sierra 中的安全/协同设计: keys 串忽略访问控制设置和 UI 提示权限

为什么 Xcode 4 不创建任何产品?