Skip to content

Commit 5029d9d

Browse files
committed
Initial attempt at implementing resumable code aware version of For in Task with TaskSeq<'T>
1 parent 0ee794b commit 5029d9d

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/FSharp.Control.TaskSeq/TaskSeq.fs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ open System.Collections.Generic
44
open System.Threading
55
open System.Threading.Tasks
66

7+
#nowarn "57"
8+
79
module TaskSeq =
810
// F# BUG: the following module is 'AutoOpen' and this isn't needed in the Tests project. Why do we need to open it?
911
open FSharp.Control.TaskSeqBuilders
@@ -324,3 +326,33 @@ module TaskSeq =
324326
let fold folder state source = Internal.fold (FolderAction folder) state source
325327

326328
let foldAsync folder state source = Internal.fold (AsyncFolderAction folder) state source
329+
330+
[<AutoOpen>]
331+
module AsyncSeqExtensions =
332+
open Microsoft.FSharp.Core.CompilerServices
333+
334+
// Add asynchronous for loop to the 'async' computation builder
335+
type Microsoft.FSharp.Control.AsyncBuilder with
336+
337+
member x.For(tasksq: IAsyncEnumerable<'T>, action: 'T -> Async<unit>) =
338+
tasksq
339+
|> TaskSeq.iterAsync (action >> Async.StartAsTask)
340+
|> Async.AwaitTask
341+
342+
// Add asynchronous for loop to the 'task' computation builder
343+
type Microsoft.FSharp.Control.TaskBuilder with
344+
345+
member inline this.For
346+
(
347+
tasksq: IAsyncEnumerable<'T>,
348+
body: 'T -> TaskCode<'TOverall, unit>
349+
) : TaskCode<'TOverall, unit> =
350+
TaskCode<'TOverall, unit>(fun sm ->
351+
this
352+
.Using(
353+
tasksq.GetAsyncEnumerator(CancellationToken()),
354+
(fun e ->
355+
// TODO: fix 'true' with e.MoveNextAsync()
356+
this.While((fun () -> true), (fun sm -> (body e.Current).Invoke(&sm))))
357+
)
358+
.Invoke(&sm))

0 commit comments

Comments
 (0)