Skip to content

Commit e27663e

Browse files
committed
Provisional implementation of a variant of CancellationToken implementation in CE
1 parent 6496832 commit e27663e

File tree

4 files changed

+76
-9
lines changed

4 files changed

+76
-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: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ module LowPriority =
565565

566566
else
567567
Debug.logInfo "at TaskLike bind: await further"
568-
568+
sm.Data.cancellationToken.ThrowIfCancellationRequested()
569569
sm.Data.awaiter <- awaiter
570570
sm.Data.current <- ValueNone
571571
false)
@@ -623,6 +623,10 @@ module HighPriority =
623623
//
624624
member inline _.Bind(task: Task<'T>, continuation: ('T -> ResumableTSC<'U>)) =
625625
ResumableTSC<'U>(fun sm ->
626+
// WTF???
627+
//let x = Func<Task<_>>(fun _ -> task)
628+
//Task<'TResult>.Run(x, sm.Data.cancellationToken)
629+
626630
let mutable awaiter = task.GetAwaiter()
627631
let mutable __stack_fin = true
628632

@@ -644,15 +648,21 @@ module HighPriority =
644648

645649
else
646650
Debug.logInfo "at Bind: await further"
647-
651+
sm.Data.cancellationToken.ThrowIfCancellationRequested()
648652
sm.Data.awaiter <- awaiter
649653
sm.Data.current <- ValueNone
650654
false)
651655

652-
// Binding to a cancellation token. This allows `do! someCancellationToken`
653-
member inline _.Bind(myToken: CancellationToken, continuation: (unit -> ResumableTSC<'T>)) : ResumableTSC<'T> =
656+
//// Binding to a cancellation token. This allows `do! someCancellationToken`
657+
//member inline _.Bind(cancellationToken, continuation: (unit -> ResumableTSC<'T>)) : ResumableTSC<'T> =
658+
// ResumableTSC<'T>(fun sm ->
659+
// sm.Data.cancellationToken <- cancellationToken
660+
// (continuation ()).Invoke(&sm))
661+
662+
[<CustomOperation "cancellationToken">]
663+
member inline _.SetCancellationToken(cancellationToken, continuation: (unit -> ResumableTSC<'T>)) : ResumableTSC<'T> =
654664
ResumableTSC<'T>(fun sm ->
655-
sm.Data.cancellationToken <- myToken
665+
sm.Data.cancellationToken <- cancellationToken
656666
(continuation ()).Invoke(&sm))
657667

658668
member inline _.Bind(computation: Async<'T>, continuation: ('T -> ResumableTSC<'U>)) =

src/FSharp.Control.TaskSeq/TaskSeqBuilder.fsi

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

210210
member inline Bind: task: Task<'T> * continuation: ('T -> ResumableTSC<'U>) -> ResumableTSC<'U>
211211
member inline Bind: computation: Async<'T> * continuation: ('T -> ResumableTSC<'U>) -> ResumableTSC<'U>
212+
//member inline Bind:
213+
// cancellationToken: CancellationToken * continuation: (unit -> ResumableTSC<'T>) -> ResumableTSC<'T>
214+
[<CustomOperation "cancellationToken">]
215+
member inline SetCancellationToken:
216+
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
@@ -76,10 +76,11 @@ module internal TaskSeqInternal =
7676
KeyNotFoundException("The predicate function or index did not satisfy any item in the task sequence.")
7777
|> raise
7878

79-
let inline withCancellationToken (cancellationToken: CancellationToken) (source: taskSeq<'T>) = taskSeq {
80-
do! cancellationToken
81-
yield! source
82-
}
79+
//let inline withCancellationToken (cancellationToken2: CancellationToken) (source: taskSeq<'T>) = taskSeq {
80+
// // COMPILE ERROR HERE
81+
// cancellationToken cancellationToken2
82+
// yield! source
83+
//}
8384

8485
let isEmpty (source: TaskSeq<_>) =
8586
checkNonNull (nameof source) source

0 commit comments

Comments
 (0)