[Concurrency] Continuations for interfacing async tasks with synchronous code

Based on the current structured concurrency pitch, I would expect this to be written as follows, no continuation-specific cancellation functionality needed:

func download(url: URL) async throws -> Data? {
    var urlSessionTask: URLSessionTask?

    return try Task.withCancellationHandler { urlSessionTask?.cancel() }
    operation: {
        return try await withUnsafeThrowingContinuation { continuation in
            urlSessionTask = URLSession.shared.dataTask(with: url) { data, _, error in
                if let error = error {
                    // Ideally translate NSURLErrorCancelled to CancellationError here
                    continuation.resume(throwing: error)
                } else {
                    continuation.resume(returning: data)
                }
            }
            urlSessionTask?.resume()
        }
    }
}
1 Like