From 3d0d28ad3b972b5ef74176528d894140f9c11b56 Mon Sep 17 00:00:00 2001 From: Matthias Dittrich Date: Sat, 24 Jun 2017 17:41:11 +0200 Subject: [PATCH 1/6] add test and fix #3254 --- .../Microsoft.FSharp.Control/AsyncType.fs | 17 ++++++++++++++++- src/fsharp/FSharp.Core/control.fs | 4 ++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs index a883b2ecf5..da9c8b858d 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs @@ -162,7 +162,22 @@ type AsyncType() = this.WaitASec t Assert.IsTrue (t.IsCompleted) Assert.AreEqual(s, t.Result) - + + [] + member this.RunSynchronouslyCancellationWithDelayedResult () = + let cts = new CancellationTokenSource() + let tcs = TaskCompletionSource() + let _ = cts.Token.Register(fun () -> tcs.SetResult 42) + let a = async { + cts.CancelAfter (100) + let! result = tcs.Task |> Async.AwaitTask + return result } + + try + Async.RunSynchronously(a, cancellationToken = cts.Token) + |> ignore + with :? OperationCanceledException as o -> () + [] member this.ExceptionPropagatesToTask () = let a = async { diff --git a/src/fsharp/FSharp.Core/control.fs b/src/fsharp/FSharp.Core/control.fs index e8231ecfaf..db86c7bfa3 100644 --- a/src/fsharp/FSharp.Core/control.fs +++ b/src/fsharp/FSharp.Core/control.fs @@ -1557,7 +1557,7 @@ namespace Microsoft.FSharp.Control else args.cont completedTask.Result)) |> unfake - task.ContinueWith(Action>(continuation), continueWithExtra args.aux.token) |> ignore |> fake + task.ContinueWith(Action>(continuation)) |> ignore |> fake let continueWithUnit (task : Task, args, useCcontForTaskCancellation) = @@ -1572,7 +1572,7 @@ namespace Microsoft.FSharp.Control else args.cont ())) |> unfake - task.ContinueWith(Action(continuation), continueWithExtra args.aux.token) |> ignore |> fake + task.ContinueWith(Action(continuation)) |> ignore |> fake #endif #if FX_NO_REGISTERED_WAIT_HANDLES From d3f535795725d507305ac12dc23a433c93c0f2e1 Mon Sep 17 00:00:00 2001 From: Matthias Dittrich Date: Sat, 24 Jun 2017 17:58:31 +0200 Subject: [PATCH 2/6] remove continueWithExtra --- src/fsharp/FSharp.Core/control.fs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/fsharp/FSharp.Core/control.fs b/src/fsharp/FSharp.Core/control.fs index db86c7bfa3..05554c813e 100644 --- a/src/fsharp/FSharp.Core/control.fs +++ b/src/fsharp/FSharp.Core/control.fs @@ -1536,14 +1536,6 @@ namespace Microsoft.FSharp.Control // Contains helpers that will attach continuation to the given task. // Should be invoked as a part of protectedPrimitive(withResync) call module TaskHelpers = - let private continueWithExtra token = -#if FSCORE_PORTABLE_OLD || FSCORE_PORTABLE_NEW - token |> ignore - TaskContinuationOptions.None -#else - token -#endif - let continueWith (task : Task<'T>, args, useCcontForTaskCancellation) = let continuation (completedTask : Task<_>) : unit = From aeeaa5014f7a8f0b90823a8adb6993073fef0326 Mon Sep 17 00:00:00 2001 From: Matthias Dittrich Date: Sat, 24 Jun 2017 18:11:15 +0200 Subject: [PATCH 3/6] add timeout attribute --- .../FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs index da9c8b858d..6abb1f1b69 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs @@ -163,7 +163,7 @@ type AsyncType() = Assert.IsTrue (t.IsCompleted) Assert.AreEqual(s, t.Result) - [] + [] member this.RunSynchronouslyCancellationWithDelayedResult () = let cts = new CancellationTokenSource() let tcs = TaskCompletionSource() From cf55e6b013d5dc5a7ab881ac26df42d416f331f5 Mon Sep 17 00:00:00 2001 From: Matthias Dittrich Date: Sat, 24 Jun 2017 18:23:08 +0200 Subject: [PATCH 4/6] don't delegate the cancellationtoken to the operationcancelledexception. --- src/fsharp/FSharp.Core/control.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.Core/control.fs b/src/fsharp/FSharp.Core/control.fs index 05554c813e..371a52af2c 100644 --- a/src/fsharp/FSharp.Core/control.fs +++ b/src/fsharp/FSharp.Core/control.fs @@ -1542,7 +1542,7 @@ namespace Microsoft.FSharp.Control args.aux.trampolineHolder.Protect((fun () -> if completedTask.IsCanceled then if useCcontForTaskCancellation - then args.aux.ccont (new OperationCanceledException(args.aux.token)) + then args.aux.ccont (new OperationCanceledException()) else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask))) elif completedTask.IsFaulted then args.aux.econt (MayLoseStackTrace(completedTask.Exception)) @@ -1557,7 +1557,7 @@ namespace Microsoft.FSharp.Control args.aux.trampolineHolder.Protect((fun () -> if completedTask.IsCanceled then if useCcontForTaskCancellation - then args.aux.ccont (new OperationCanceledException(args.aux.token)) + then args.aux.ccont (new OperationCanceledException()) else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask))) elif completedTask.IsFaulted then args.aux.econt (MayLoseStackTrace(completedTask.Exception)) From 41718f157b877542d98eeded32302fe09f7c7a09 Mon Sep 17 00:00:00 2001 From: Matthias Dittrich Date: Sat, 24 Jun 2017 22:03:33 +0200 Subject: [PATCH 5/6] Revert "add timeout attribute" This reverts commit aeeaa5014f7a8f0b90823a8adb6993073fef0326. --- .../FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs index 6abb1f1b69..da9c8b858d 100644 --- a/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs +++ b/src/fsharp/FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs @@ -163,7 +163,7 @@ type AsyncType() = Assert.IsTrue (t.IsCompleted) Assert.AreEqual(s, t.Result) - [] + [] member this.RunSynchronouslyCancellationWithDelayedResult () = let cts = new CancellationTokenSource() let tcs = TaskCompletionSource() From 75657e1f46fb0cda2c49178af81c3a276ef8de77 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 27 Jun 2017 10:43:14 +0100 Subject: [PATCH 6/6] Update control.fs --- src/fsharp/FSharp.Core/control.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/FSharp.Core/control.fs b/src/fsharp/FSharp.Core/control.fs index 371a52af2c..05554c813e 100644 --- a/src/fsharp/FSharp.Core/control.fs +++ b/src/fsharp/FSharp.Core/control.fs @@ -1542,7 +1542,7 @@ namespace Microsoft.FSharp.Control args.aux.trampolineHolder.Protect((fun () -> if completedTask.IsCanceled then if useCcontForTaskCancellation - then args.aux.ccont (new OperationCanceledException()) + then args.aux.ccont (new OperationCanceledException(args.aux.token)) else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask))) elif completedTask.IsFaulted then args.aux.econt (MayLoseStackTrace(completedTask.Exception)) @@ -1557,7 +1557,7 @@ namespace Microsoft.FSharp.Control args.aux.trampolineHolder.Protect((fun () -> if completedTask.IsCanceled then if useCcontForTaskCancellation - then args.aux.ccont (new OperationCanceledException()) + then args.aux.ccont (new OperationCanceledException(args.aux.token)) else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask))) elif completedTask.IsFaulted then args.aux.econt (MayLoseStackTrace(completedTask.Exception))