【发布时间】:2021-02-16 07:53:33
【问题描述】:
我有问题。我需要一个可以使用的资源。我已经实现了这个机制:
func shouldRetry(request: Request, error: Error) -> Bool {
let semaphore = DispatchSemaphore(value: 0)
var shouldRetry: Bool = false
self.interceptor?.retry(request.response, for: self.session!, dueTo: error, completion: { (retryResult) in
switch retryResult {
case .retry:
shouldRetry = true
semaphore.signal()
case .doNotRetry:
shouldRetry = false
semaphore.signal()
case .retryWithDelay(let delay):
shouldRetry = true
self.retryTimer = Timer.scheduledTimer(withTimeInterval: delay, repeats: false, block: { (_) in
semaphore.signal()
self.retryTimer?.invalidate()
self.retryTimer = nil
})
}
})
semaphore.wait()
return shouldRetry
}
问题是interceptor?.retry func use 是在信号量的同一个线程中调用的,这会阻塞进程。有什么建议吗?
更新:
我解决了我的问题。我继承了 URLProtocol 抽象类。这个类与 URLSession 一起使用,它可以暂停 HTTP 调用,制作异步代码并恢复
【问题讨论】:
-
你想达到什么目的? Semaphore.wait 阻塞线程直到获得 semaphore.signal,这是预期的行为
-
shouldRetry 返回一个用于在条件下重试发布自身的组合扩展中的 Bool。在此之前,我调用了一个执行异步代码的重试方法,然后调用了一个带有枚举的闭包(retry,retryWithDelay,doNotRetry)。在返回布尔之前,我等待关闭(我正在尝试复制 Alamofire 拦截器)。一切正常,但是如果再次进行 HTTP 调用,重试方法使用相同的线程,并且所有管道都卡住了。
-
您“只是”需要从同步设计切换到异步设计。不幸的是,您可能必须从头开始。所以你的“所有作品”的说法是相当乐观的;)
标签: swift concurrency grand-central-dispatch semaphore