diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 12404b0..d5c367e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -17,7 +17,7 @@ jobs:
# Builds for Debug and Release configurations
configuration: [Debug, Release]
# Builds for Ubuntu, Windows, and macOS
- os: [ubuntu-latest, windows-latest, macOS-latest, macos-14]
+ os: [ubuntu-latest, windows-latest, macOS-latest]
fail-fast: false
runs-on: ${{ matrix.os }}
diff --git a/paket.dependencies b/paket.dependencies
index fba2022..3203573 100644
--- a/paket.dependencies
+++ b/paket.dependencies
@@ -21,7 +21,7 @@ group Test
nuget TimeProviderExtensions
nuget YoloDev.Expecto.TestSdk >= 0.14.2
nuget Microsoft.NET.Test.Sdk >= 17.7.2
- nuget FSharp.Control.TaskSeq
+ nuget FSharp.Control.TaskSeq 0.4.0
// [ FAKE GROUP ]
group Build
@@ -41,5 +41,5 @@ group Build
nuget Fake.BuildServer.GitHubActions ~> 6
nuget Argu
nuget Octokit >= 0.50
- nuget MSBuild.StructuredLogger 2.1.858
+ nuget MSBuild.StructuredLogger 2.2.243
diff --git a/paket.lock b/paket.lock
index cbac881..03b69f4 100644
--- a/paket.lock
+++ b/paket.lock
@@ -283,7 +283,7 @@ NUGET
System.Security.Principal.Windows (>= 5.0) - restriction: || (&& (>= monoandroid) (< netstandard1.3)) (&& (< monoandroid) (>= netcoreapp2.0)) (>= monotouch) (&& (< net46) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (>= netcoreapp2.1) (>= uap10.1) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos)
Microsoft.Win32.SystemEvents (7.0) - restriction: >= net6.0
Mono.Posix.NETStandard (1.0) - restriction: >= netstandard2.0
- MSBuild.StructuredLogger (2.1.858)
+ MSBuild.StructuredLogger (2.2.243)
Microsoft.Build.Framework (>= 17.5) - restriction: >= netstandard2.0
Microsoft.Build.Utilities.Core (>= 17.5) - restriction: >= netstandard2.0
Newtonsoft.Json (13.0.3) - restriction: >= netstandard2.0
@@ -369,8 +369,8 @@ NUGET
FsCheck (>= 2.16.5 < 3.0) - restriction: >= net6.0
FsCheck (2.16.6) - restriction: >= net6.0
FSharp.Core (>= 4.2.3) - restriction: || (>= net452) (>= netstandard1.6)
- FSharp.Control.TaskSeq (0.3)
- FSharp.Core (>= 6.0.2) - restriction: >= netstandard2.1
+ FSharp.Control.TaskSeq (0.4)
+ FSharp.Core (>= 6.0.1) - restriction: >= netstandard2.1
FSharp.Core (7.0.401) - restriction: >= netstandard2.1
Microsoft.Bcl.AsyncInterfaces (8.0)
System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (>= net462) (&& (>= netstandard2.0) (< netstandard2.1))
diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props
index e7a7266..dadfdcc 100644
--- a/tests/Directory.Build.props
+++ b/tests/Directory.Build.props
@@ -3,5 +3,6 @@
false
true
+ $(NoWarn);FS0044
diff --git a/tests/IcedTasks.Tests/AsyncExTests.fs b/tests/IcedTasks.Tests/AsyncExTests.fs
index dd13630..8e0930e 100644
--- a/tests/IcedTasks.Tests/AsyncExTests.fs
+++ b/tests/IcedTasks.Tests/AsyncExTests.fs
@@ -690,7 +690,7 @@ module AsyncExTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
asyncEx {
@@ -719,7 +719,7 @@ module AsyncExTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
use cts = new CancellationTokenSource()
@@ -754,7 +754,7 @@ module AsyncExTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
use cts = new CancellationTokenSource()
@@ -776,6 +776,47 @@ module AsyncExTests =
}
}
+
+#if TEST_NETSTANDARD2_1 || TEST_NET6_0_OR_GREATER
+ testCaseAsync "TaskSeq receives CancellationToken"
+ <| async {
+
+ do!
+ asyncEx {
+
+ let loops = 1
+
+ let mutable CancellationToken = CancellationToken.None
+
+ let asyncSeq =
+ taskSeq {
+ for i in 0..loops do
+ do!
+ asyncEx {
+ let! ct = Async.CancellationToken
+ CancellationToken <- ct
+ }
+
+ yield ()
+ }
+
+ use cts = new CancellationTokenSource()
+
+ let actual =
+ asyncEx {
+ for i in asyncSeq do
+ do! Task.Yield()
+ }
+
+ do!
+ Async.StartAsTask(actual, cancellationToken = cts.Token)
+ |> Async.AwaitTask
+
+ Expect.equal CancellationToken cts.Token ""
+ }
+ }
+#endif
+
]
]
diff --git a/tests/IcedTasks.Tests/CancellablePoolingValueTaskTests.fs b/tests/IcedTasks.Tests/CancellablePoolingValueTaskTests.fs
index 5809886..05e25f1 100644
--- a/tests/IcedTasks.Tests/CancellablePoolingValueTaskTests.fs
+++ b/tests/IcedTasks.Tests/CancellablePoolingValueTaskTests.fs
@@ -2,6 +2,7 @@ namespace IcedTasks.Tests
open System
open Expecto
+open FSharp.Control
open System.Threading
open System.Threading.Tasks
open IcedTasks
@@ -801,7 +802,7 @@ module CancellablePoolingValueTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (fun _ -> valueTask { do! Task.Yield() })
let! actual =
cancellablePoolingValueTask {
@@ -832,7 +833,7 @@ module CancellablePoolingValueTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (fun _ -> valueTask { do! Task.Yield() })
use cts = new CancellationTokenSource()
@@ -865,7 +866,7 @@ module CancellablePoolingValueTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (fun _ -> valueTask { do! Task.Yield() })
use cts = new CancellationTokenSource()
@@ -884,6 +885,41 @@ module CancellablePoolingValueTaskTests =
""
}
}
+ testCaseAsync "TaskSeq receives CancellationToken"
+ <| async {
+
+ do!
+ cancellablePoolingValueTask {
+
+ let loops = 1
+
+ let mutable CancellationToken = CancellationToken.None
+
+ let asyncSeq =
+ taskSeq {
+ for i in 0..loops do
+ do!
+ cancellablePoolingValueTask {
+ let! ct = CancellableTask.getCancellationToken ()
+ CancellationToken <- ct
+ }
+
+ yield ()
+ }
+
+ use cts = new CancellationTokenSource()
+
+ let actual =
+ cancellablePoolingValueTask {
+ for i in asyncSeq do
+ do! Task.Yield()
+ }
+
+ do! actual cts.Token
+
+ Expect.equal CancellationToken cts.Token ""
+ }
+ }
]
diff --git a/tests/IcedTasks.Tests/CancellableTaskTests.fs b/tests/IcedTasks.Tests/CancellableTaskTests.fs
index 54a1b12..2651be2 100644
--- a/tests/IcedTasks.Tests/CancellableTaskTests.fs
+++ b/tests/IcedTasks.Tests/CancellableTaskTests.fs
@@ -2,9 +2,10 @@ namespace IcedTasks.Tests
open System
open Expecto
+open IcedTasks
+open FSharp.Control
open System.Threading
open System.Threading.Tasks
-open IcedTasks
module CancellableTaskTests =
open System.Collections.Concurrent
@@ -763,7 +764,7 @@ module CancellableTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
cancellableTask {
@@ -793,7 +794,7 @@ module CancellableTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
use cts = new CancellationTokenSource()
@@ -827,7 +828,7 @@ module CancellableTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
use cts = new CancellationTokenSource()
@@ -845,8 +846,44 @@ module CancellableTaskTests =
cts.Token
""
}
+ }
+#if TEST_NETSTANDARD2_1 || TEST_NET6_0_OR_GREATER
+ testCaseAsync "TaskSeq receives CancellationToken"
+ <| async {
+
+ do!
+ cancellableTask {
+
+ let loops = 1
+
+ let mutable CancellationToken = CancellationToken.None
+
+ let asyncSeq =
+ taskSeq {
+ for i in 0..loops do
+ do!
+ cancellableTask {
+ let! ct = CancellableTask.getCancellationToken ()
+ CancellationToken <- ct
+ }
+ yield ()
+ }
+
+ use cts = new CancellationTokenSource()
+
+ let actual =
+ cancellableTask {
+ for i in asyncSeq do
+ do! Task.Yield()
+ }
+
+ do! actual cts.Token
+
+ Expect.equal CancellationToken cts.Token ""
+ }
}
+#endif
]
testList "MergeSources" [
diff --git a/tests/IcedTasks.Tests/CancellableValueTaskTests.fs b/tests/IcedTasks.Tests/CancellableValueTaskTests.fs
index c2d289f..48bf7ff 100644
--- a/tests/IcedTasks.Tests/CancellableValueTaskTests.fs
+++ b/tests/IcedTasks.Tests/CancellableValueTaskTests.fs
@@ -6,6 +6,7 @@ open System.Threading
open System.Threading.Tasks
open IcedTasks
open System.Collections.Generic
+open FSharp.Control
module CancellableValueTaskTests =
open TimeProviderExtensions
@@ -801,7 +802,7 @@ module CancellableValueTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
cancellableValueTask {
@@ -831,7 +832,7 @@ module CancellableValueTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
use cts = new CancellationTokenSource()
@@ -864,7 +865,7 @@ module CancellableValueTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
use cts = new CancellationTokenSource()
@@ -884,6 +885,46 @@ module CancellableValueTaskTests =
}
}
+#if TEST_NETSTANDARD2_1 || TEST_NET6_0_OR_GREATER
+ testCaseAsync "TaskSeq receives CancellationToken"
+ <| async {
+
+ do!
+ cancellableValueTask {
+
+ let loops = 1
+
+ let mutable CancellationToken = CancellationToken.None
+
+ let asyncSeq =
+ taskSeq {
+ for i in 0..loops do
+ do!
+ cancellableValueTask {
+ let! ct =
+ CancellableValueTask.getCancellationToken ()
+
+ CancellationToken <- ct
+ }
+
+ yield ()
+ }
+
+ use cts = new CancellationTokenSource()
+
+ let actual =
+ cancellableValueTask {
+ for i in asyncSeq do
+ do! Task.Yield()
+ }
+
+ do! actual cts.Token
+
+ Expect.equal CancellationToken cts.Token ""
+ }
+ }
+#endif
+
]
testList "MergeSources" [
diff --git a/tests/IcedTasks.Tests/Expect.fs b/tests/IcedTasks.Tests/Expect.fs
index f2bc584..fdbcdd0 100644
--- a/tests/IcedTasks.Tests/Expect.fs
+++ b/tests/IcedTasks.Tests/Expect.fs
@@ -179,7 +179,7 @@ module AsyncEnumerable =
member this.MoveNextAsync() = moveNext ()
member this.DisposeAsync() = dispose ()
- type AsyncEnumerable<'T>(e: IEnumerable<'T>, beforeMoveNext: Func<_, ValueTask>) =
+ type AsyncEnumerable<'T>(e: IEnumerable<'T>, beforeMoveNext: Func<_, ValueTask>) =
let mutable lastEnumerator = None
member this.LastEnumerator = lastEnumerator
@@ -211,3 +211,64 @@ module AsyncEnumerable =
let forXtoY<'T> x y beforeMoveNext =
AsyncEnumerable([ x..y ], Func<_, _>(beforeMoveNext))
+
+#if TEST_NETSTANDARD2_1 || TEST_NET6_0_OR_GREATER
+
+[]
+module AsyncEnumerableExtensions =
+ open FSharp.Control
+ open Microsoft.FSharp.Core.CompilerServices
+
+ type TaskSeqBuilder with
+
+ member inline _.Bind
+ (
+ [] task: CancellableTask<'T>,
+ continuation: ('T -> ResumableTSC<'U>)
+ ) =
+ ResumableTSC<'U>(fun sm ->
+ let mutable awaiter =
+ task sm.Data.cancellationToken
+ |> Awaitable.GetTaskAwaiter
+
+ let mutable __stack_fin = true
+
+ if not (Awaiter.IsCompleted awaiter) then
+ let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ __stack_fin <- __stack_yield_fin
+
+ if __stack_fin then
+ let result = Awaiter.GetResult awaiter
+ (continuation result).Invoke(&sm)
+ else
+ sm.Data.awaiter <- awaiter
+ sm.Data.current <- ValueNone
+ false
+ )
+
+ member inline _.Bind
+ (
+ [] task: CancellableValueTask<'T>,
+ continuation: ('T -> ResumableTSC<'U>)
+ ) =
+ ResumableTSC<'U>(fun sm ->
+ let mutable awaiter =
+ task sm.Data.cancellationToken
+ |> Awaitable.GetAwaiter
+
+ let mutable __stack_fin = true
+
+ if not (Awaiter.IsCompleted awaiter) then
+ let __stack_yield_fin = ResumableCode.Yield().Invoke(&sm)
+ __stack_fin <- __stack_yield_fin
+
+ if __stack_fin then
+ let result = Awaiter.GetResult awaiter
+ (continuation result).Invoke(&sm)
+ else
+ sm.Data.awaiter <- awaiter
+ sm.Data.current <- ValueNone
+ false
+ )
+
+#endif
diff --git a/tests/IcedTasks.Tests/PoolingValueTaskDynamicTests.fs b/tests/IcedTasks.Tests/PoolingValueTaskDynamicTests.fs
index 2eeae9d..3b3056d 100644
--- a/tests/IcedTasks.Tests/PoolingValueTaskDynamicTests.fs
+++ b/tests/IcedTasks.Tests/PoolingValueTaskDynamicTests.fs
@@ -9,6 +9,7 @@ open System.Threading.Tasks
open IcedTasks
open System.Collections.Generic
+
module PoolingValueTaskDynamicTests =
open System.Runtime.CompilerServices
open System.Collections.Generic
@@ -611,7 +612,7 @@ module PoolingValueTaskDynamicTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
dPoolingValueTask {
diff --git a/tests/IcedTasks.Tests/PoolingValueTaskTests.fs b/tests/IcedTasks.Tests/PoolingValueTaskTests.fs
index 31d4e2b..ed51fc0 100644
--- a/tests/IcedTasks.Tests/PoolingValueTaskTests.fs
+++ b/tests/IcedTasks.Tests/PoolingValueTaskTests.fs
@@ -596,7 +596,7 @@ module PoolingValueTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
poolingValueTask {
diff --git a/tests/IcedTasks.Tests/TaskBackgroundTests.fs b/tests/IcedTasks.Tests/TaskBackgroundTests.fs
index f1e3636..83cde23 100644
--- a/tests/IcedTasks.Tests/TaskBackgroundTests.fs
+++ b/tests/IcedTasks.Tests/TaskBackgroundTests.fs
@@ -598,7 +598,7 @@ module TaskBackgroundTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
backgroundTask {
diff --git a/tests/IcedTasks.Tests/TaskDynamicTests.fs b/tests/IcedTasks.Tests/TaskDynamicTests.fs
index dbac837..2c75964 100644
--- a/tests/IcedTasks.Tests/TaskDynamicTests.fs
+++ b/tests/IcedTasks.Tests/TaskDynamicTests.fs
@@ -610,7 +610,7 @@ module TaskDynamicTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
dTask {
diff --git a/tests/IcedTasks.Tests/TaskTests.fs b/tests/IcedTasks.Tests/TaskTests.fs
index c0c3797..889a35b 100644
--- a/tests/IcedTasks.Tests/TaskTests.fs
+++ b/tests/IcedTasks.Tests/TaskTests.fs
@@ -598,7 +598,7 @@ module TaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
task {
diff --git a/tests/IcedTasks.Tests/ValueTaskDynamicTests.fs b/tests/IcedTasks.Tests/ValueTaskDynamicTests.fs
index fcf3c5f..9ca74fb 100644
--- a/tests/IcedTasks.Tests/ValueTaskDynamicTests.fs
+++ b/tests/IcedTasks.Tests/ValueTaskDynamicTests.fs
@@ -609,7 +609,7 @@ module ValueTaskDynamicTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
dValueTask {
diff --git a/tests/IcedTasks.Tests/ValueTaskTests.fs b/tests/IcedTasks.Tests/ValueTaskTests.fs
index d97ae5c..2c13a92 100644
--- a/tests/IcedTasks.Tests/ValueTaskTests.fs
+++ b/tests/IcedTasks.Tests/ValueTaskTests.fs
@@ -597,7 +597,7 @@ module ValueTaskTests =
AsyncEnumerable.forXtoY
0
loops
- (fun _ -> valueTaskUnit { do! Task.Yield() })
+ (cancellableValueTask { do! Task.Yield() })
let! actual =
valueTask {