在iOS应用中限制dispatch_async任务时间

时间:2016-02-12 15:11:33

标签: ios swift grand-central-dispatch

我使用dispatch_async进行一些服务器调用。 有时,由于互联网连接速度慢,此呼叫需要花费很多时间。

如何设置以秒为单位的限制 - 例如:任务有3秒钟完成,否则停止。

2 个答案:

答案 0 :(得分:1)

如果您从服务器请求数据,则应该使用NSURLSession之类的内容。当您设置会话时,您可以设置您想要的超时。

答案 1 :(得分:1)

作为MultiColour Pixel says,您应该真正使用NSURLSession

但是,如果您仍在寻找GCD答案,那么它就是......

您可以轻松使用信号量来实现请求的超时。

您只需要创建一个初始值为0的信号量,然后使用dispatch_semaphore_wait以便在网络任务完成时等待信号量发出信号,或者请求超时。

因此,如果您的网络任务是同步的,那么您需要执行以下操作......

let queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL) // your GCD queue

...

dispatch_async(queue, {

    let semaphore = dispatch_semaphore_create(0) // create semaphore

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        self.doNetworkTask()
        dispatch_semaphore_signal(semaphore); // signal semaphore on completion
    })

    let timeout = dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 * Double(NSEC_PER_SEC))) // 3 second time-out
    let returnValue = dispatch_semaphore_wait(semaphore, timeout)

    guard returnValue == 0 else { // return value is non-zero if the request timed out

        // request timed out, cancel the request here.
        self.stopNetworkTask()
        return // prevent further execution if network task was unsucessful
    }

    dispatch_async(dispatch_get_main_queue(), {
        // do processing after request success
    })

})

或者,如果您的网络任务是异步的......

let queue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL) // your GCD queue

...

dispatch_async(queue, {

    let semaphore = dispatch_semaphore_create(0) // create semaphore

    self.doNetworkTaskWithCompletion({
        dispatch_semaphore_signal(semaphore); // signal semaphore on completion
    })

    let timeout = dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 * Double(NSEC_PER_SEC))) // 3 second time-out
    let returnValue = dispatch_semaphore_wait(semaphore, timeout)

    guard returnValue == 0 else { // return value is non-zero if the request timed out

        // request timed out, cancel the request here.
        self.stopNetworkTask()
        return // prevent further execution if network task was unsucessful
    }

    dispatch_async(dispatch_get_main_queue(), {
        // do processing after request success
    })

})