在主要执行线程中启动分离任务和调用非隔离函数之间的区别

3

假设我在一个被注释为@MainActor的类中,以便所有函数都与主要actor相关联。我试图理解以下操作之间的区别:

func bar() {
  Task.detached(priority: .background) {
    await foo()
  }
}

func foo() async {
  ...
}

vs

func bar() {
  Task(priority: .background) {
    await foo()
  }
}

nonisolated func foo() async {
  ...
}

他们是相同的吗?

在“执行foo的演员将被隔离到哪里”的方面,两种情况是一样的,但可能还有其他方面我没有考虑。另外请注意,如果foo是“非隔离的”,则可以通过其他代码在非主线程上运行。 - Sweeper
等等,我的例子中foo不是在非主线程上运行吗? - Tometoyou
不对。在你的第一个例子中,foo 被隔离到主角色中,因为它在带有 @MainActor 声明的类内部。这并不重要它是从不在主角色上的分离任务中调用的;第一个 foo 仍将在主角色上运行。 - Rob
1个回答

1

你说:

Imagine I'm in a class annotated with @MainActor so that all the functions are tied to the main actor. I'm trying to understand what the difference is between doing the following:

func bar() {
  Task.detached(priority: .background) {
    await foo()
  }
}

func foo() async {
  ...
}

bar方法创建了一个非结构化任务,因为它是一个detached任务,所以不在当前的actor上。但是该任务将会await foo方法,而foo方法将在主要的actor上运行。foo方法所在的类带有@MainActor标识,这意味着无论你在哪个Swift并发上下文中调用它,它都与该actor隔离。

但是,在这种情况下,启动一个只等待actor隔离函数的detached任务没有太多意义。

你继续说:

vs

func bar() {
  Task(priority: .background) {
    await foo()
  }
}

nonisolated func foo() async {
  ...
}
在这种情况下,bar将在当前(主)actor上启动一个任务,但它将等待非隔离的foo的结果(即不隔离到主actor)。
因此,第一个示例中的foo是actor隔离的,但在第二个示例中不是。

所以,如果我想要从非主线程运行foo函数,我需要使用第二种方法,但是需要使用分离的任务吗? - Tometoyou
是的,可以使用分离的任务和非隔离的函数或单独的演员。 - Rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接