Rai*_*kas 19 ios async-await swift structured-concurrency swift-concurrency
我看过Explore structured concurrency in Swift视频和我能找到的其他相关视频/文章/书籍(Sundell 的 swift、用 swift 进行黑客攻击、Ray Renderlich),但所有示例都非常琐碎 - 异步函数通常只有 1 个异步调用。这在现实生活中的代码中应该如何工作?
例如:
...
task = Task {
var longRunningWorker: LongRunningWorker? = nil
do {
var fileURL = state.fileURL
if state.needsCompression {
longRunningWorker = LongRunningWorker(inputURL: fileURL)
fileURL = try await longRunningWorker!.doAsyncWork()
}
let urls = try await ApiService.i.fetchUploadUrls()
if let image = state.image, let imageData = image.jpegData(compressionQuality: 0.8) {
guard let imageUrl = urls.signedImageUrl else {
fatalError("Cover art supplied but art upload URL is nil")
}
try await ApiService.i.uploadData(url: imageUrl, data: imageData)
}
let fileData = try Data(contentsOf: state.fileUrl)
try await ApiService.i.uploadData(url: urls.signedFileUrl, data: fileData)
try await ApiService.i.doAnotherAsyncNetworkCall()
} catch {
longRunningWorker?.deleteFilesIfNecessary()
throw error
}
}
...
Run Code Online (Sandbox Code Playgroud)
然后在某个时候我会打电话task.cancel()。
谁负责取消什么?到目前为止我看到的示例将使用try Task.checkCancellation(),但对于此代码,该行应该每隔几行出现一次 - 这是应该如何完成的?
如果 API 服务使用 URLSession,则调用将在 iOS 15 上取消,但我们不使用 URLSession 代码的异步变体,因此我们必须手动取消调用。这也适用于所有长时间运行的工作代码。
我还认为我可以在每个异步函数中添加此检查,但基本上所有异步函数都会具有相同的样板代码,这又似乎是错误的,而且我在任何视频中都没有看到这样做。
编辑:我已删除回调调用,因为这些调用与问题无关。
Rob*_*Rob 16
我们自己的取消逻辑的实现有两种基本模式:
用于withTaskCancellationHandler(operation:onCancel:)包装可取消的异步流程。
当调用可取消的遗留 API 并将其包装在Task. 这样,取消任务可以主动停止旧 API 中的异步进程,而不是等到到达手动isCancelled或checkCancellation调用为止。此模式适用于 iOS 13/14 URLSessionAPI 或任何提供取消方法的异步 API。
定期检查isCancelled或try checkCancellation。
这在您使用循环执行一些手动、计算密集型过程的情况下非常有用。
关于处理协作取消的许多讨论往往都集中在这些方法上,但在处理遗留的可取消 API 时,上述方法withTaskCancellationHandler通常是更好的解决方案。
因此,我个人会专注于在包装一些遗留异步流程的方法中实现协作取消。通常,取消逻辑会向上渗透,通常不需要在调用链中进一步进行额外检查,通常由您可能已经拥有的任何错误处理逻辑来处理。
| 归档时间: |
|
| 查看次数: |
10693 次 |
| 最近记录: |