我在文档中找不到以下行为的定义
// task-less context
Task.detached {
try await myThrowingFunction()
runWhenSuccessful()
}
该方法在抛出行上返回并丢弃错误,runWhenSuccessful()
将永远不会被调用。虽然它在某种程度上是有意义的,但我至少期望它会触发Assert失败或未处理错误。
既然我不能处理任何父任务中的错误,那么正确的处理方法是什么呢?
我是否每次都要将闭包中的所有内容 Package 在do/catch
中?
2条答案
按热度按时间bjp0bcyl1#
由于某些原因,Task被设计为在闭包内部抛出任何错误时静默失败。任务确实有一个
result
属性,当任务完成时,您可以读取它,但根据文档,它将阻塞执行它的当前线程。我的首选解决方案是为
Task
创建一个方便的初始化器,它接受一个失败闭包。这是我的自定义初始化器的样子,以及它的使用方式:
ep6jt1vc2#
虽然还没有正式提出(* 读者:如果你想的话就请吧!* ),有talk on the Swift forums,只允许
Task<Void, Never>
是“@discardableResult
”将是一个足够好的解决方案的问题。现在,
Task.init
和Task.detached
始终是discardable
。如果不是这样,那么“Result … is unused
”消息将使程序员意识到需要采取进一步的行动……...例如,当任务的
Success
不是Void
......或被轻推以存储任务,并在以后处理错误。
我支持这项拟议的改变。但是,仍然可以像现在这样,使用下划线忽略一个错误完成的任务,我不认为下划线很好地代表了意图:
强制处理错误的唯一方法是让
operation
闭包不会使用显式的Never
抛出类型系统。invalid conversion from throwing function of type '@Sendable () async throws -> ()' to non-throwing function type '@Sendable () async -> ()'
do/catch
:显式的
Error
可能比_ = Task
更能表达意图: