Swift 任务没有按预期在主要参与者上运行

Bil*_*ill 5 swift swift-concurrency

我在一个简单的 Mac 测试项目中有以下代码:

\n
@main\nclass AppDelegate: NSObject, NSApplicationDelegate {\n  func applicationDidFinishLaunching(_ aNotification: Notification) {\n    print("are we initially on the main thread: \\(Thread.isMainThread)")\n\n    Task {\n      print("is new task on main thread: \\(Thread.isMainThread)")\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Swift 语言指南中,我看到以下内容:

\n
\n

要创建在当前参与者上运行的非结构化任务,请调用 Task.init(priority:operation:) 初始值设定项。要创建不属于当前参与者的非结构化任务(更具体地称为分离任务),请调用 Task.detached(priority:operation:) 类方法。

\n
\n

因此,由于 AppDelegate 代码在主要参与者上运行,并且我正在创建一个正常(即非分离)任务,因此我希望它的子任务也在主要参与者上运行。

\n

但当我运行这个测试应用程序时,情况并非如此:

\n
are we initially on the main thread: true\nis new task on main thread: false\n
Run Code Online (Sandbox Code Playgroud)\n

根据我所读到的有关 Swift 并发性的内容,我预计新任务将在主要参与者上调度并运行,因此Thread.isMainThread在该任务中也是如此。

\n

为什么事实并非如此?

\n

Sou*_*unt 0

这里要做出的重要区别是,在主线程上运行代码并不意味着代码在MainActor. 要让您的方法始终运行,MainActor您可以将该方法与属性applicationDidFinishLaunching隔离。在快速并发中,如果您将方法/属性与参与者隔离,那么您在其中创建的任何任务也将继承参与者上下文。目前,您没有指定参与者隔离,因此会看到此行为。MainActor@MainActorTask.init