In Swift, unlike e.g. C#, it’s not the task itself that’s awaited. I’m pretty sure this would have to be await Task { … }.value
.
Ignoring the missing .value
this does work and is the current way to have an enforced clean-up, but we have to resort to unstructured Concurrency which indicates that we are lacking a feature here. We ought to be able to express everything with structured Concurrency so that the compiler can reason about this.
Having a defer
where we can opt-out of cancellation would be great.
Fun gotcha: In my experience, Task.sleep(nanoseconds:)
returns immediately if you do that. Sleeping the current task next-to-forever seems to work with .max / 2
nanoseconds however. Maybe it's internally reinterpreting the UInt64
as signed?
(Also you probably mean to try? await
that so it handles and ignores CancellationError
.)
This would check out: setting only the MSb (i.e. (.max >> 1) + 1
or ~UInt64(Int64.max)
) returns just as immediately. That should either be fixed or documented.
The source of that bug is described here: Fix bug in Dispatch executor preventing long sleeps by rauhul · Pull Request #64304 · apple/swift · GitHub but I haven't found the time to follow up on my patch.