Repository navigation
CancellationToken not used/registered #179
Description
Activity
I could've sworn I answered this a while ago, while I was still out sailing. Anyway, I am back now and I will pick this up again after some housekeeping and fixing some low hanging fruit.
- addedbugSomething isn't workingSomething isn't workingtopic: taskseq-ceRelated to the taskseq computation expression builders or overloadsRelated to the taskseq computation expression builders or overloads
on Oct 29, 2023 I had the idea to make a registration on the cancellation token, and setting an exception on promiseOfValueOrEnd there. There would be some book-keeping with disposing the registration, but nothing too big.
Note that your example is currently not using a cancellation check. While we are working on better support for cancellation tokens (see, for instance, #78, #133 and #184 for some background), these won't solve your issue, as inside your implementation you will need to decide how often and when you will check for the cancellation token.
let infinite () = taskSeq { while true do yield 1 // this is essentially a synchronous loop, and there's no check on cancellation here }
Now, we could certainly consider checking for the cancellation token inside the CE, for instance during
MoveNext, but tbh, I am not certain it is wise to abort that way.For instance, consider a scenario where you need to pull pairs of data, and you coded that such that after pulling each two items, you check for cancellation. If then this library would throw in the middle of these two
MoveNextoperations because someone canceled, it would break your application. Perhaps we could support this scenario optionally, though.All that said, we do need to make the cancellation token accessible from inside the CE, which currently isn't the case.
I understand that it is not a given which semantics are the most desirable. Especially since normal tasks and task-likes do not provide any natural hook for cancellation.
While I'm not the biggest fan of the C# approach with ConfiguredCancelableAsyncEnumerable (which would require some work to support, as it does not implement IAsyncEnumerable) maybe something similar is a reasonable solution. E.g. a function or extension that returns a special task-like, that can accept a cancellation token when bound. Or maybe merge with IcedTasks, as I have seen suggested elsewhere.
approach with
ConfiguredCancelableAsyncEnumerableThis is in the pipeline, see #167.
Or maybe merge with IcedTasks, as I have seen suggested elsewhere.
Merge, no, these libraries support very different use cases. Support, yes. It was indeed discussed, see #188.
that can accept a cancellation token when bound
All functions that consume the input sequence will get an overload to accept a cancellation token. We will also update the
Async<'T>support such that we will pick its cancellation token, plus add more overloads to supportAsync(not to be confused withTask) out of the box.TLDR: we will very much support cancellation in full, to the same extend that
taskdoes (since it is its natural equivalent) and where applicable, a little bit better.My point in the previous comment, however, is that none of this will change your use case: your code is impossible to cancel, because you didn't write cancellation support in your own code. Now, that's understandable, given that you currently cannot access the cancellation token from within the
taskSeqcomputation expression, and that's yet another change that is very much in the pipeline.- added a commit that references this issue
on Mar 8, 2026 - added a commit that references this issue
on Mar 8, 2026
Hi.
Thanks for working on this. I have been exploring this repository since I wanted to do something similar, and I noticed that even when manually passing in a cancellation token, it is not directly acted upon. So for example
will run forever. However, if something like
Async.Sleep()is bound inside the taskSeq, it will end with an exception, since the token is actually passed to the async when it is bound.Do you think it would make sense to set the
promiseOfValueOrEndto a cancelled exception (which seems to be the ideomatic dotnet way) or complete(false) when the token is cancelled? I.e, using the CancellationTokenRegistration to abort MoveNextAsync on cancellation?