Open
Description
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
let consumeManually (enumerable: IAsyncEnumerable<int>) (token: CancellationToken) = task {
do! Task.Yield()
let mutable hasRead = false
use enumerator = enumerable.GetAsyncEnumerator(token)
let! canRead = enumerator.MoveNextAsync()
hasRead <- canRead
while hasRead do
let _here = enumerator.Current
let! canRead = enumerator.MoveNextAsync()
hasRead <- canRead
return ()
}
let infinite () = taskSeq {
while true do
yield 1
}
[<Fact>]
let usesCancellationToken () = task {
use src = new CancellationTokenSource()
let readToEnd = consumeManually (infinite()) src.Token
do! Task.Delay(100)
src.Cancel()
do! readToEnd
}
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 promiseOfValueOrEnd
to 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?