gpt4 book ai didi

swift - 如何为等待函数调用添加超时

转载 作者:行者123 更新时间:2023-12-05 08:03:03 25 4
gpt4 key购买 nike

为等待函数添加超时的最佳方法是什么?

Example:

/// lets pretend this is in a library that I'm using and I can't mess with the guts of this thing
func fetchSomething() async -> Thing? {
// fetches something
}

// if fetchSomething() never returns then doSomethingElse() is never ran. Is there anyway to add a timeout to this system?
let thing = await fetchSomething()
doSomethingElse()

我想让系统在 fetchSomething() 永远不会返回的情况下更加健壮。如果这是使用组合,我会使用超时运算符。

最佳答案

可以创建一个任务,然后如果它在特定时间段内没有完成则取消它。例如,并行启动两个任务:

// cancel the fetch after 2 seconds

func fetchSomethingWithTimeout() async throws -> Thing {
let fetchTask = Task {
try await fetchSomething()
}

let timeoutTask = Task {
try await Task.sleep(nanoseconds: 2 * NSEC_PER_SEC)
fetchTask.cancel()
}

let result = try await fetchTask.value
timeoutTask.cancel()

return result
}

// here is a random mockup that will take between 1 and 3 seconds to finish

func fetchSomething() async throws -> Thing {
let duration: TimeInterval = .random(in: 1...3)

try await Task.sleep(nanoseconds: UInt64(TimeInterval(NSEC_PER_SEC) * duration))

return Thing()
}

如果 fetchTask 先完成,它将到达 timeoutTask.cancel 并停止它。如果 timeoutTask 先完成,它将取消 fetchTask

显然,这取决于 fetchTask 的实现。它不仅应该检测取消,还应该在取消时抛出错误(可能是 CancellationError )。如果没有有关 fetchTask 实现的详细信息,我们无法进一步发表评论。

例如,在上面的例子中,我不会返回一个可选的Thing?,而是返回Thing,但让它throw如果取消则出错。


我犹豫要不要提它,但是虽然上面假设 fetchSomething 表现良好(即可取消),但即使它不工作(即运行doSomethingElse 在一些合理的时间表中,即使 fetchSomething “永远不会返回”)。

但这本质上是一种不稳定的情况,因为 fetchSomething 使用的资源在它完成之前无法恢复。 Swift 不提供抢先取消,因此虽然我们可以轻松解决确保 doSomethingElse 最终运行的战术问题,但如果 fetchSomething 可能永远不会在某个合理的时间表内完成,您有更深层次的问题。

你真的应该找到一个可取消的 fetchSomething 版本,如果它还没有的话。

关于swift - 如何为等待函数调用添加超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74710155/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com