Skip to content

Instantly share code, notes, and snippets.

@SLAVONchick
Created August 10, 2023 11:03
Show Gist options
  • Save SLAVONchick/1ac95175b2f9304b6d6af3f9be7835e5 to your computer and use it in GitHub Desktop.
Save SLAVONchick/1ac95175b2f9304b6d6af3f9be7835e5 to your computer and use it in GitHub Desktop.
open System
open System.Collections.Generic
open System.IO
open System.Runtime.CompilerServices
open System.Threading
open System.Threading.Tasks
open FSharp.Control
module AsyncEnum =
let inline retype<'T,'U> (x:'T) : 'U = (# "" x : 'U #)
let inline private asTaskSeq< ^a, ^e, ^awaitable, ^awaiter, 'T, 'U
when ^a:(member GetAsyncEnumerator: unit -> ^e)
and ^e:(member MoveNextAsync: unit -> ^awaitable)
and ^e:(member Current : 'T)
and ^awaitable:(member GetAwaiter: unit -> ^awaiter)
and ^awaiter:(member GetResult: unit -> 'U)
and ^awaiter:(member get_IsCompleted: unit -> bool)
and ^awaiter :> ICriticalNotifyCompletion > (source : ^a)= taskSeq {
let enumerator = source.GetAsyncEnumerator()
let! tmpMoveNext = task { return! enumerator.MoveNextAsync() }
let mutable moveNext = retype tmpMoveNext
while moveNext do
yield enumerator.Current
let! tmpMoveNext = task { return! enumerator.MoveNextAsync() }
moveNext <- retype tmpMoveNext
()
}
let withCancellation predicate (ct: CancellationToken) (source: IAsyncEnumerable<'T>) = taskSeq {
for item in (asTaskSeq (source.WithCancellation(ct))) do
yield predicate item
}
let results =
File.ReadLinesAsync("path/to/file.txt")
|> AsyncEnum.withCancellation Console.WriteLine CancellationToken.None
|> TaskSeq.toArray
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment