Description
Currently, it is not very clear how users can pass a CancellationToken
through. While the CE has support for cancellation tokens, and the token is passed on to GetAsyncEnumerator(ct)
, unless users access the interface directly, there is currently no way to pass a cancellation token.
There are four, not necessarily exclusive ways, to implement this.
- Add
TaskSeq.setCancellationToken
, which will return ataskSeq
with the given cancellation token - Add a
do!
overload that allows writingtaskSeq { do! myCancelToken }
in your CE, otherwise behaving the same as (1) - Add a custom operation, such that you can write
taskSeq { cancellationToken myCancelToken }
in your CE - Add a parameter to the
taskSeq
CE constructor. However, if possible, this may not be easily discoverable
There are upsides and downsides to each of these approaches. I think the first option, together with a getCancellationToken
should at least be supported.
However, there are other challenges as well. The helper functions in the TaskSeq
module all use the CancellationToken()
constructor (that is: no cancellation support). The taskSeq
builder in that respect is a bit of a mixed beast. Yes, you can pass in a cancellation token, but you have to do it manually, and then, using any of the helpers will basically ignore this token.
That's not a good position to be in. Probably, code like source.GetAsyncEnumerator(CancellationToken())
should become something like source.GetAsyncEnumerator(TaskSeq.getCancellationToken source)
. Which runs into another issue: while the state machine has a property for the cancellation token, any other implementation of IAsyncEnumerable<'T>
does not, which requires a type check to detect.
Adding all this magic comes at a cost. In AsyncSeq
and Async
this was resolved by adding overloads that take an optional cancellation token. Not ideal either.