Skip to content

Commit 05e4e0a

Browse files
committed
Initial attempt at implementing resumable code aware version of For in Task with TaskSeq<'T>
1 parent 230fce3 commit 05e4e0a

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
@@ -322,3 +324,33 @@ module TaskSeq =
322324
let fold folder state source = Internal.fold (FolderAction folder) state source
323325

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

0 commit comments

Comments
 (0)