Skip to content

Commit 9bd1f49

Browse files
committed
Provisional implementation of a variant of CancellationToken implementation in CE
1 parent 3a9a47c commit 9bd1f49

File tree

4 files changed

+80
-9
lines changed

4 files changed

+80
-9
lines changed

src/FSharp.Control.TaskSeq.Test/TaskSeq.Do.Tests.fs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ open FsUnit
66
open Xunit
77

88
open FSharp.Control
9+
open System.Threading
910

1011
[<Fact>]
1112
let ``CE taskSeq: use 'do'`` () =
@@ -56,3 +57,53 @@ let ``CE taskSeq: use 'do!' with a task-delay`` () =
5657
}
5758
|> verifyEmpty
5859
|> Task.map (fun _ -> value |> should equal 2)
60+
61+
//module CancellationToken =
62+
// [<Fact>]
63+
// let ``CE taskSeq: use 'do!' with a default cancellation-token`` () =
64+
// let mutable value = 0
65+
66+
// taskSeq {
67+
// do value <- value + 1
68+
// do! CancellationToken()
69+
// do value <- value + 1
70+
// }
71+
// |> verifyEmpty
72+
// |> Task.map (fun _ -> value |> should equal 2)
73+
74+
// [<Fact>]
75+
// let ``CE taskSeq: use 'do!' with a timer cancellation-token - explicit`` () = task {
76+
// let mutable value = 0
77+
// use tokenSource = new CancellationTokenSource(500)
78+
79+
// return!
80+
// taskSeq {
81+
// do! tokenSource.Token // this sets the token for this taskSeq
82+
// do value <- value + 1
83+
// do! Task.Delay(300, tokenSource.Token)
84+
// do! Task.Delay(300, tokenSource.Token)
85+
// do! Task.Delay(300, tokenSource.Token)
86+
// do value <- value + 1
87+
// }
88+
// |> verifyEmpty
89+
// |> Task.map (fun _ -> value |> should equal 2)
90+
// }
91+
92+
93+
// [<Fact>]
94+
// let ``CE taskSeq: use 'do!' with a timer cancellation-token - implicit`` () = task {
95+
// let mutable value = 0
96+
// use tokenSource = new CancellationTokenSource(500)
97+
98+
// return!
99+
// taskSeq {
100+
// do! tokenSource.Token // this sets the token for this taskSeq
101+
// do value <- value + 1
102+
// do! Task.Delay(300)
103+
// do! Task.Delay(300)
104+
// do! Task.Delay(300)
105+
// do value <- value + 1
106+
// }
107+
// |> verifyEmpty
108+
// |> Task.map (fun _ -> value |> should equal 2)
109+
// }

src/FSharp.Control.TaskSeq/TaskSeqBuilder.fs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ module LowPriority =
567567

568568
else
569569
Debug.logInfo "at TaskLike bind: await further"
570-
570+
sm.Data.cancellationToken.ThrowIfCancellationRequested()
571571
sm.Data.awaiter <- awaiter
572572
sm.Data.current <- ValueNone
573573
false)
@@ -631,6 +631,10 @@ module HighPriority =
631631
//
632632
member inline _.Bind(task: Task<'TResult1>, continuation: ('TResult1 -> ResumableTSC<'T>)) : ResumableTSC<'T> =
633633
ResumableTSC<'T>(fun sm ->
634+
// WTF???
635+
//let x = Func<Task<_>>(fun _ -> task)
636+
//Task<'TResult>.Run(x, sm.Data.cancellationToken)
637+
634638
let mutable awaiter = task.GetAwaiter()
635639
let mutable __stack_fin = true
636640

@@ -652,15 +656,25 @@ module HighPriority =
652656

653657
else
654658
Debug.logInfo "at Bind: await further"
655-
659+
sm.Data.cancellationToken.ThrowIfCancellationRequested()
656660
sm.Data.awaiter <- awaiter
657661
sm.Data.current <- ValueNone
658662
false)
659663

660-
// Binding to a cancellation token. This allows `do! someCancellationToken`
661-
member inline _.Bind(myToken: CancellationToken, continuation: (unit -> ResumableTSC<'T>)) : ResumableTSC<'T> =
664+
//// Binding to a cancellation token. This allows `do! someCancellationToken`
665+
//member inline _.Bind(cancellationToken, continuation: (unit -> ResumableTSC<'T>)) : ResumableTSC<'T> =
666+
// ResumableTSC<'T>(fun sm ->
667+
// sm.Data.cancellationToken <- cancellationToken
668+
// (continuation ()).Invoke(&sm))
669+
670+
[<CustomOperation "cancellationToken">]
671+
member inline _.SetCancellationToken
672+
(
673+
cancellationToken,
674+
continuation: (unit -> ResumableTSC<'T>)
675+
) : ResumableTSC<'T> =
662676
ResumableTSC<'T>(fun sm ->
663-
sm.Data.cancellationToken <- myToken
677+
sm.Data.cancellationToken <- cancellationToken
664678
(continuation ()).Invoke(&sm))
665679

666680
[<AutoOpen>]

src/FSharp.Control.TaskSeq/TaskSeqBuilder.fsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,8 @@ module HighPriority =
191191
type TaskSeqBuilder with
192192

193193
member inline Bind: task: Task<'TResult1> * continuation: ('TResult1 -> ResumableTSC<'T>) -> ResumableTSC<'T>
194+
//member inline Bind:
195+
// cancellationToken: CancellationToken * continuation: (unit -> ResumableTSC<'T>) -> ResumableTSC<'T>
196+
[<CustomOperation "cancellationToken">]
197+
member inline SetCancellationToken:
198+
cancellationToken: CancellationToken * continuation: (unit -> ResumableTSC<'T>) -> ResumableTSC<'T>

src/FSharp.Control.TaskSeq/TaskSeqInternal.fs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ module internal TaskSeqInternal =
6060
KeyNotFoundException("The predicate function or index did not satisfy any item in the async sequence.")
6161
|> raise
6262

63-
let inline withCancellationToken (cancellationToken: CancellationToken) (source: taskSeq<'T>) = taskSeq {
64-
do! cancellationToken
65-
yield! source
66-
}
63+
//let inline withCancellationToken (cancellationToken2: CancellationToken) (source: taskSeq<'T>) = taskSeq {
64+
// // COMPILE ERROR HERE
65+
// cancellationToken cancellationToken2
66+
// yield! source
67+
//}
6768

6869
let isEmpty (source: taskSeq<_>) = task {
6970
use e = source.GetAsyncEnumerator(CancellationToken())

0 commit comments

Comments
 (0)