File tree Expand file tree Collapse file tree 2 files changed +27
-1
lines changed
FSharp.Core.Unittests/FSharp.Core/Microsoft.FSharp.Control Expand file tree Collapse file tree 2 files changed +27
-1
lines changed Original file line number Diff line number Diff line change @@ -299,6 +299,28 @@ type AsyncModule() =
299299 Assert.IsTrue( isSet())
300300 for _ i = 1 to 3 do test()
301301
302+ [<Test>]
303+ member this. ``OnCancel.RaceBetweenCancellationAndDispose`` () =
304+ let flag = ref 0
305+ let cts = new System.Threading.CancellationTokenSource()
306+ let go = async {
307+ use disp =
308+ cts.Cancel()
309+ { new IDisposable with
310+ override __.Dispose () = incr flag }
311+ while true do
312+ do ! Async.Sleep 50
313+ }
314+ try
315+ Async.RunSynchronously ( go, cancellationToken = cts.Token)
316+ with
317+ #if FX_ NO_ OPERATION_ CANCELLED
318+ _ -> ()
319+ #else
320+ :? System.OperationCanceledException -> ()
321+ #endif
322+ Assert.AreEqual( 1 , ! flag)
323+
302324 [<Test>]
303325 member this. ``OnCancel.CancelThatWasSignalledBeforeRunningTheComputation`` () =
304326 let test () =
Original file line number Diff line number Diff line change @@ -909,7 +909,11 @@ namespace Microsoft.FSharp.Control
909909
910910 /// Implement use/Dispose
911911 let usingA ( r : 'T :> IDisposable ) ( f : 'T -> Async < 'a >) : Async < 'a > =
912- tryFinallyA ( fun () -> Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.Dispose r) ( callA f r)
912+ let mutable x = 0
913+ let disposeFunction _ =
914+ if Interlocked.CompareExchange(& x, 1 , 0 ) = 0 then
915+ Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.Dispose r
916+ tryFinallyA disposeFunction ( callA f r) |> whenCancelledA disposeFunction
913917
914918 let ignoreA p =
915919 bindA p ( fun _ -> doneA)
You can’t perform that action at this time.
0 commit comments