I need to support cancellation of a function that returns an object that can be cancelled after initiation. In my case, the requester
class is in a 3rd party library that I can't modify.
actor MyActor {
...
func doSomething() async throws -> ResultData {
var requestHandle: Handle?
return try await withTaskCancellationHandler {
requestHandle?.cancel() // COMPILE ERROR: "Reference to captured var 'requestHandle' in concurrently-executing code"
} operation: {
return try await withCheckedThrowingContinuation{ continuation in
requestHandle = requester.start() { result, error in
if let error = error
continuation.resume(throwing: error)
} else {
let myResultData = ResultData(result)
continuation.resume(returning: myResultData)
}
}
}
}
}
...
}
I have reviewed other SO questions and this thread: https://forums.swift.org/t/how-to-use-withtaskcancellationhandler-properly/54341/4
There are cases that are very similar, but not quite the same. This code won't compile because of this error:
"Reference to captured var 'requestHandle' in concurrently-executing code"
I assume the compiler is trying to protect me from using the requestHandle
before it's initialized. But I'm not sure how else to work around this problem. The other examples shown in the Swift Forum discussion thread all seem to have a pattern where the requester
object can be initialized before calling its start
function.
I also tried to save the requestHandle
as a class variable, but I got a different compile error at the same location:
Actor-isolated property 'profileHandle' can not be referenced from a Sendable closure
doSomething
function was already in anactor
where I tried to do something similar to what you suggested (I updated question). But it looks like wrapping the cancellation handle block withTask{ await requestHandle?.cancel() }
is the key here. Btw, if I remove theTask
wrapper in the body of thewithCheckedThrowingContinuation
closure, it compiles cleanly as well - so not sure if this is essential to your fix? Have yet to test this actually supports cancellation or survives stress testing. Not even sure how to write a unit test for this. – Jutta