How can I get the current Task?

Hi everyone,

Is it possible to get the current task from within an async function?
I found withUnsafeCurrentTask(body:) and UnsafeCurrentTask. The documentation of UnsafeCurrentTask says:

[...] use the task property of UnsafeCurrentTask to access an instance of Task that you can store long-term and interact with outside of the closure body. [...]

However, it looks like this property is not available (Xcode 13 Beta 3) and I think it is also not mentioned in the Proposal.

Context: I want to get the current task during the execution of the closure that I pass to Task.init(priority:operation:) to be able to cancel the current task later.

Thanks
David

1 Like

Given below is my understanding (I could be wrong):

You could use try Task.checkCancellation to check if the current task is cancelled, and I don't think you need to pass it around. If a parent task is cancelled all it's child tasks would be cancelled.

Refer:

hello,
Thanks for help @SomuYadav, I have same issue Really appreciate for help.

The problem is that this Task I have does not have a parent Task. I use Task.checkCancellation() to check for cancellation but I want to get the Task to be able to cancel the Task in the first place.

The thing is that I call a method which does not use the new concurrency features from Swift and which may want to cancel the current task asynchronously. I want to give this method a Task so that it can cancel it. Because I need to call this method from inside the operation closure from Task.init(priority:operation:) I can't use the Task returned from the initializer.

3 Likes

I'm also facing a similar use case, I'm not sure what's the best design.

I access the AuthorizationController environment from a SwiftUI view.
In this view, when a button is tapped, I call a function that looks like this:

func doSomething() {
    Task {
        do {
            let result = try await featureModel.doSomething(
                with: authorizationController
            )
        } catch {
            print(error)
        }
    }
}

Inside the feature model (which is an ObservableObject), I want to access this Task and be able to cancel it.

I could create a Published property inside the feature model that stores the Task and every view that interacts with it must do featureModel.currentTask = Task { ... }, but this doesn't seem like good design (me or some other developer might forget to assign the task to the property).

I could also move the whole Task { ... } closure to inside featureModel.doSomething(with:) and not make it async but this would mean I can't return something inside of it and I would have to introduce a completion closure parameter to it to complete with the result.

The ideal design IMO is to keep featureModel.doSomething(with:) and regardless from which Task it's called from, it can get it at run-time and cancel it.

Does Swift have this ability or another possible solution that I'm not aware of?

It looks like you're wanting this:

func doSomething() {
  withUnsafeCurrentTask { currentTask in
    currentTask.cancel()
  }
}

Does that meet your needs?

1 Like