Thanks for the reply, Kevin!
I think I didn't make my use case clear enough, though.
Off the main thread, it's ENTIRELY possible that your task will start AFTER the system has already started expiring background tasks
In all situations, I'm calling MyTaskManager*.start() during normal app operations, and in the happy path, doTheWork() actually finishes before the app is ever backgrounded. I am not calling start() in response to applicationDidEnterBackground or anything like that. I'm calling it in response to, say, a button tap.
The doTheWork() function performs some laggy network back-and-forth, so there's a nontrivial likelihood of:
the parent Task is started while the app is in the foreground,
the parent Task (nearly) immediately calls beginBackgroundTask,
a few seconds later, the user backgrounds the app,
the child Task continues to attempt to finish its work in the allotted time extension
And if it takes too long, then the expiration handler gets called, and I give up on the Task by canceling it. At some point (very quickly) later, the child Task finishes early via cooperative cancellation, and the parent Task calls endBackgroundTask(_:)
And I hope that the user doesn't background the app so quickly next time, thereby giving it a better chance to finish while the app is still foregrounded.