@@ -12,6 +12,7 @@ open System.Threading.Tasks
1212open System.Runtime .ExceptionServices
1313#if ! FABLE_ COMPILER
1414open System.Linq
15+ open System.Threading .Channels
1516#endif
1617
1718#nowarn " 40" " 3218"
@@ -375,6 +376,17 @@ module AsyncSeq =
375376 member x.MoveNext () = async { return None }
376377 member x.Dispose () = () } }
377378
379+ let emptyAsync < 'T > ( action : Async < unit >) : AsyncSeq < 'T > =
380+ { new IAsyncEnumerable< 'T> with
381+ member x.GetEnumerator () =
382+ { new IAsyncEnumerator< 'T> with
383+ member x.MoveNext () =
384+ async {
385+ do ! action
386+ return None
387+ }
388+ member x.Dispose () = () } }
389+
378390 let singleton ( v : 'T ) : AsyncSeq < 'T > =
379391 { new IAsyncEnumerable< 'T> with
380392 member x.GetEnumerator () =
@@ -1811,6 +1823,75 @@ module AsyncSeq =
18111823 #endif
18121824
18131825
1826+ #if ! FABLE_ COMPILER
1827+ open System.Threading .Channels
1828+
1829+ let toChannel ( writer : ChannelWriter < 'a >) ( xs : AsyncSeq < 'a >) : Async < unit > =
1830+ async {
1831+ try
1832+ do !
1833+ xs
1834+ |> iterAsync
1835+ ( fun x ->
1836+ async {
1837+ if not ( writer.TryWrite( x)) then
1838+ let! ct = Async.CancellationToken
1839+
1840+ do !
1841+ writer.WriteAsync( x, ct). AsTask()
1842+ |> Async.AwaitTask
1843+ })
1844+
1845+ writer.Complete()
1846+ with exn ->
1847+ writer.Complete( error = exn)
1848+ }
1849+
1850+ let fromChannel ( reader : ChannelReader < 'a >) : AsyncSeq < 'a > =
1851+ asyncSeq {
1852+ let mutable keepGoing = true
1853+
1854+ while keepGoing do
1855+ let mutable item = Unchecked.defaultof< 'a>
1856+
1857+ if reader.TryRead(& item) then
1858+ yield item
1859+ else
1860+ let! ct = Async.CancellationToken
1861+
1862+ let! hasMoreData =
1863+ reader.WaitToReadAsync( ct). AsTask()
1864+ |> Async.AwaitTask
1865+
1866+ if not hasMoreData then
1867+ keepGoing <- false
1868+ }
1869+
1870+ let prefetch ( numberToPrefetch : int ) ( xs : AsyncSeq < 'a >) : AsyncSeq < 'a > =
1871+ if numberToPrefetch = 0 then
1872+ xs
1873+ else
1874+ if numberToPrefetch < 1 then
1875+ invalidArg ( nameof numberToPrefetch) " must be at least zero"
1876+ asyncSeq {
1877+ let opts = BoundedChannelOptions( numberToPrefetch)
1878+ opts.SingleWriter <- true
1879+ opts.SingleReader <- true
1880+
1881+ let channel = Channel.CreateBounded( opts)
1882+
1883+ let! fillChannelTask =
1884+ toChannel channel.Writer xs
1885+ |> Async.StartChild
1886+
1887+ yield !
1888+ append
1889+ ( fromChannel channel.Reader)
1890+ ( emptyAsync fillChannelTask)
1891+ }
1892+
1893+ #endif
1894+
18141895
18151896[<AutoOpen>]
18161897module AsyncSeqExtensions =
0 commit comments