Repository navigation
Support withCancellation #167
Description
Activity
This is actually very interesting. Reading up on the design decisions for
WithCancellation, as Don Syme and myself were about creating our own solution, but it is, obviously, better to use dotnet's own methods, if they are applicable.Just checked, this method is part of NetStandard 2.1, so I can actually add it. Another method in those extensions that is very interesting is
ToBlockingEnumerable. This is a .NET 7+ extension, but I might take its code for the blocking operations I have, to ensure similar behavior.Related discussion: #133
- addedtopic: surface areaAdds functions to the public surface areaAdds functions to the public surface areafeature requestNew feature or enhancement requestNew feature or enhancement request
on Oct 29, 2023 This turns out to be much harder to support than I thought. But one of the soon-to-be-made changes is going to be a move to static methods, so we can support adding a cancellation token in each call immediately, removing the need for calling
WithCancellation, but that means threading an overload through the whole system.To support this, we either need to overload every single method such that it accepts that type, or we have to go SRTP (and/or with an SRTP overload).
Instead, I may consider something like
ofWithCancellation(ugly method name, I know), which would itself return anIAsyncEnumerablebut with a collected cancellation token. This is, however, not ideal, as the token should be given toGetEnumerator(token). Hmm, I'll think a bit more about this.The reason this is non-trivial is because
ConfiguredCancelableAsyncEnumerable<T>is a struct and does not implement any useful interface. I'm also a little confused as to why MS chose to internally effectively callConfigureAwait(true), which, from library code, is considered bad practice in general (and can lead to deadlocks).Maybe raise an issues on .NET repo about the use of
ConfiguredCancelableAsyncEnumerable<T>?That likely wouldn't help. It is a
structfor a reason. While it keeps a reference to theIAsyncEnumerable<_>internally, it makes the overhead of making your enumerable cancelable really small. There's no need for anewobjIL instruction.github-actions commented
on Mar 8, 2026 on Mar 8, 2026 – with GitHub Actions · Hidden as outdatedshow commentMore actions/repo-assist Add this
withCancellationin a PRReacted by github-actions- changed the title
[-]Support `ConfiguredCancelableAsyncEnumerable<'T>`[/-][+]Support withCancellation[/+]on Mar 14, 2026 - added a commit that references this issue
on Mar 14, 2026 github-actions commented
on Mar 14, 2026 on Mar 14, 2026 – with GitHub ActionsContributorMore actionsPull request created: #339
Generated by Repo Assist
github-actions commented
on Mar 14, 2026 on Mar 14, 2026 – with GitHub ActionsContributorMore actions🤖 Repo Assist here — following
@dsyme's request, I've implementedTaskSeq.withCancellationand opened a draft PR.The implementation is a lightweight wrapper that passes the supplied
CancellationTokendirectly toGetAsyncEnumerator, mirroring.WithCancellation()semantics without requiring any interaction withConfiguredCancelableAsyncEnumerable(T):// Usage — replaces .WithCancellation(cancellationToken): source.AsAsyncEnumerable() |> TaskSeq.withCancellation cancellationToken |> TaskSeq.iterAsync (fun x -> builder.Add(x))
The PR includes:
TaskSeq.withCancellation : CancellationToken -> TaskSeq<'T> -> TaskSeq<'T>in the public API- 10 tests covering null-check, token threading, pre/mid-iteration cancellation, and combinator composition
- All 4711 existing tests still pass
Generated by Repo Assist for issue #167 · ◷
To install this agentic workflow, run
gh aw add githubnext/agentics/workflows/repo-assist.md@346204513ecfa08b81566450d7d599556807389f
When you call
.WithCancellation(cancellationToken)onIAsyncEnumerable<'T>you getSystem.Runtime.CompilerServices. ConfiguredCancelableAsyncEnumerable<'T>which is not currently supported.So that this code does not work