, I understand that a reference cycle between self <-> self.task will not happen, at least by observing deinit is called for this case. However, will keeping the instance of Task beyond its body's execution be considered an anti pattern, or are there any problematic consequences of doing so?
In and of itself, keeping a Task around has no issue. It's really the easiest way to access the results. As for the cycle, someone familiar with Task's implementation will have chime in. On the face of it there would be a cycle here unless Task specifically breaks it by dereferencing the closure when the work is complete.
It shouldn't be possible for an ended task to form cycles, since the only value it holds on to is the final result or error at the end of the task. The task object does keep some additional structures allocated until it can be deallocated, though, so holding on to a lot of task handles might keep more memory allocated than necessary, but holding on to a single task handle should not be a huge deal.
There should never be a reference cycle, strictly speaking, because nobody owns the task's local state except for the executing task itself. Even if the executing task has an access to its own Task reference, that reference doesn't own any of the local state, only the execution context does, so when the resources held by local state are released during normal execution of the task, they won't have their lifetimes prolonged, and when the task is completely done executing, there is no local state owning any references to anything besides the completed task's result and/or error, if any.