Skip to content

Commit 145a840

Browse files
committed
Provisional implementation of a variant of CancellationToken implementation in CE
1 parent e1f5161 commit 145a840

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'`` () =
@@ -57,6 +58,56 @@ let ``CE taskSeq: use 'do!' with a task-delay`` () =
5758
|> verifyEmpty
5859
|> Task.map (fun _ -> value |> should equal 2)
5960

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+
// }
110+
60111
[<Fact>]
61112
let ``CE taskSeq: use 'do!' with Async`` () =
62113
let mutable value = 0

src/FSharp.Control.TaskSeq/TaskSeqBuilder.fs

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

557557
else
558558
Debug.logInfo "at TaskLike bind: await further"
559-
559+
sm.Data.cancellationToken.ThrowIfCancellationRequested()
560560
sm.Data.awaiter <- awaiter
561561
sm.Data.current <- ValueNone
562562
false)
@@ -614,6 +614,10 @@ module HighPriority =
614614
//
615615
member inline _.Bind(task: Task<'T>, continuation: ('T -> ResumableTSC<'U>)) =
616616
ResumableTSC<'U>(fun sm ->
617+
// WTF???
618+
//let x = Func<Task<_>>(fun _ -> task)
619+
//Task<'TResult>.Run(x, sm.Data.cancellationToken)
620+
617621
let mutable awaiter = task.GetAwaiter()
618622
let mutable __stack_fin = true
619623

@@ -635,7 +639,7 @@ module HighPriority =
635639

636640
else
637641
Debug.logInfo "at Bind: await further"
638-
642+
sm.Data.cancellationToken.ThrowIfCancellationRequested()
639643
sm.Data.awaiter <- awaiter
640644
sm.Data.current <- ValueNone
641645
false)
@@ -672,10 +676,20 @@ module HighPriority =
672676
sm.Data.current <- ValueNone
673677
false)
674678

675-
// Binding to a cancellation token. This allows `do! someCancellationToken`
676-
member inline _.Bind(myToken: CancellationToken, continuation: (unit -> ResumableTSC<'T>)) : ResumableTSC<'T> =
679+
//// Binding to a cancellation token. This allows `do! someCancellationToken`
680+
//member inline _.Bind(cancellationToken, continuation: (unit -> ResumableTSC<'T>)) : ResumableTSC<'T> =
681+
// ResumableTSC<'T>(fun sm ->
682+
// sm.Data.cancellationToken <- cancellationToken
683+
// (continuation ()).Invoke(&sm))
684+
685+
[<CustomOperation "cancellationToken">]
686+
member inline _.SetCancellationToken
687+
(
688+
cancellationToken,
689+
continuation: (unit -> ResumableTSC<'T>)
690+
) : ResumableTSC<'T> =
677691
ResumableTSC<'T>(fun sm ->
678-
sm.Data.cancellationToken <- myToken
692+
sm.Data.cancellationToken <- cancellationToken
679693
(continuation ()).Invoke(&sm))
680694

681695
[<AutoOpen>]

src/FSharp.Control.TaskSeq/TaskSeqBuilder.fsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,8 @@ module HighPriority =
198198

199199
member inline Bind: task: Task<'T> * continuation: ('T -> ResumableTSC<'U>) -> ResumableTSC<'U>
200200
member inline Bind: computation: Async<'T> * continuation: ('T -> ResumableTSC<'U>) -> ResumableTSC<'U>
201+
//member inline Bind:
202+
// cancellationToken: CancellationToken * continuation: (unit -> ResumableTSC<'T>) -> ResumableTSC<'T>
203+
[<CustomOperation "cancellationToken">]
204+
member inline SetCancellationToken:
205+
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
@@ -67,10 +67,11 @@ module internal TaskSeqInternal =
6767
KeyNotFoundException("The predicate function or index did not satisfy any item in the async sequence.")
6868
|> raise
6969

70-
let inline withCancellationToken (cancellationToken: CancellationToken) (source: taskSeq<'T>) = taskSeq {
71-
do! cancellationToken
72-
yield! source
73-
}
70+
//let inline withCancellationToken (cancellationToken2: CancellationToken) (source: taskSeq<'T>) = taskSeq {
71+
// // COMPILE ERROR HERE
72+
// cancellationToken cancellationToken2
73+
// yield! source
74+
//}
7475

7576
let isEmpty (source: taskSeq<_>) =
7677
checkNonNull (nameof source) source

0 commit comments

Comments
 (0)