问题
Why is NSURLSession
operation queue empty after creating and resuming an NSURLSessionTask?
Is there a way to tell if an NSURLSession has tasks pending?
The goal is to wait for multiple tasks to complete, but this doesn't work:
NSURLSessionUploadTask *uploadTask = [self.session uploadTaskWithStreamedRequest:request];
[uploadTask resume];
// this prints "0"
NSLog(self.session.delegateQueue.operationCount)
// this returns immediately instead of waiting for task to complete
[self.session.delegateQueue waitUntilAllOperationsAreFinished];
回答1:
I found a solution that avoids invalidating the session, using the suggested DispatchGroup
.
(answer is in Swift, while question is in ObjC ... but it's the same logic)
Note that when using, uploadTaskWithStreamedRequest:
, we need to implement an URLSessionTaskDelegate
and func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
. So, to simplify the answer, I will demonstrate the use of DispatchGroup
with uploadTaskWithRequest:from:completionHandler:
.
// strong reference to the dispatch group
let dispatchGroup = DispatchGroup()
func performManyThings() {
for _ in 1...3 {
let request = URLRequest(url: URL(string: "http://example.com")!)
dispatchGroup.enter()
let uploadTask = self.session.uploadTask(with: request, from: nil) { [weak self] _, _, _ in
self?.dispatchGroup.leave()
}
uploadTask.resume()
}
dispatchGroup.notify(queue: .main) {
// here, all the tasks are completed
}
}
回答2:
It's very easy as long as you don't care about reusing the session and don't mind doing things asynchronously:
- Call
finishTasksAndInvalidate
on the session. - Implement the
URLSession:didBecomeInvalidWithError:
method in your session delegate to do whatever work you need to do after the last task finishes.
That said, the problem with your code above is that the session doesn't have any operations until it starts the first fetch, which can't happen as long as your code is blocking the run loop. You generally should not attempt to use NSURLSession synchronously. It is almost always the wrong way to solve things. :-)
来源:https://stackoverflow.com/questions/40883042/how-to-wait-for-all-tasks-of-an-nsurlsession-to-complete