Skip to content

Commit 81cd84d

Browse files
authored
Merge pull request #9208 from dotnet/merges/master-to-release/dev16.7
Merge master to release/dev16.7
2 parents 1a798f2 + a062a34 commit 81cd84d

8 files changed

Lines changed: 76 additions & 8 deletions

File tree

src/fsharp/FSharp.Core/async.fs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,7 @@ namespace Microsoft.FSharp.Control
13681368
let cancellationToken = defaultArg cancellationToken defaultCancellationTokenSource.Token
13691369
AsyncPrimitives.StartWithContinuations cancellationToken computation id (fun edi -> edi.ThrowAny()) ignore
13701370

1371-
static member Sleep millisecondsDueTime : Async<unit> =
1371+
static member Sleep (millisecondsDueTime: int64) : Async<unit> =
13721372
CreateDelimitedUserCodeAsync (fun ctxt ->
13731373
let mutable timer = None: Timer option
13741374
let cont = ctxt.cont
@@ -1401,7 +1401,7 @@ namespace Microsoft.FSharp.Control
14011401
| Some t -> t.Dispose()
14021402
// Now we're done, so call the continuation
14031403
ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> cont()) |> unfake),
1404-
null, dueTime=millisecondsDueTime, period = -1) |> Some
1404+
null, dueTime=millisecondsDueTime, period = -1L) |> Some
14051405
with exn ->
14061406
if latch.Enter() then
14071407
// post exception to econt only if we successfully enter the latch (no other continuations were called)
@@ -1413,6 +1413,16 @@ namespace Microsoft.FSharp.Control
14131413
| _ ->
14141414
ctxt.econt edi)
14151415

1416+
static member Sleep (millisecondsDueTime: int32) : Async<unit> =
1417+
Async.Sleep (millisecondsDueTime |> int64)
1418+
1419+
[<Experimental(ExperimentalAttributeMessages.RequiresPreview)>]
1420+
static member Sleep (dueTime: TimeSpan) =
1421+
if dueTime < TimeSpan.Zero then
1422+
raise (ArgumentOutOfRangeException("dueTime"))
1423+
else
1424+
Async.Sleep (dueTime.TotalMilliseconds |> Checked.int64)
1425+
14161426
/// Wait for a wait handle. Both timeout and cancellation are supported
14171427
static member AwaitWaitHandle(waitHandle: WaitHandle, ?millisecondsTimeout:int) =
14181428
let millisecondsTimeout = defaultArg millisecondsTimeout Threading.Timeout.Infinite

src/fsharp/FSharp.Core/async.fsi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,15 @@ namespace Microsoft.FSharp.Control
282282
/// and not infinite.</exception>
283283
static member Sleep: millisecondsDueTime:int -> Async<unit>
284284

285+
/// <summary>Creates an asynchronous computation that will sleep for the given time. This is scheduled
286+
/// using a System.Threading.Timer object. The operation will not block operating system threads
287+
/// for the duration of the wait.</summary>
288+
/// <param name="dueTime">The amount of time to sleep.</param>
289+
/// <returns>An asynchronous computation that will sleep for the given time.</returns>
290+
/// <exception cref="System.ArgumentOutOfRangeException">Thrown when the due time is negative.</exception>
291+
[<Experimental(ExperimentalAttributeMessages.RequiresPreview)>]
292+
static member Sleep: dueTime:TimeSpan -> Async<unit>
293+
285294
/// <summary>Creates an asynchronous computation in terms of a Begin/End pair of actions in
286295
/// the style used in CLI APIs. For example,
287296
/// <c>Async.FromBeginEnd(ws.BeginGetWeather,ws.EndGetWeather)</c>

src/fsharp/FSharp.Core/prim-types.fsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,11 @@ namespace Microsoft.FSharp.Core
616616
/// <summary>Indicates one or more adjustments to the compiled representation of an F# type or member</summary>
617617
member Flags : CompilationRepresentationFlags
618618

619+
module internal ExperimentalAttributeMessages = begin
620+
[<Literal>]
621+
val RequiresPreview : string = "Experimental library feature, requires '--langversion:preview'"
622+
end
623+
619624
/// <summary>This attribute is used to tag values that are part of an experimental library
620625
/// feature.</summary>
621626
[<AttributeUsage (AttributeTargets.All,AllowMultiple=false)>]

tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncModule.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ module ChoiceUtils =
6363
let runChoice (ChoiceWorkflow(ops, cancelAfter)) =
6464
// Step 1. build a choice workflow from the abstract representation
6565
let completed = ref 0
66-
let returnAfter time f = async {
66+
let returnAfter (time: int) f = async {
6767
do! Async.Sleep time
6868
let _ = Interlocked.Increment completed
6969
return f ()

tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/AsyncType.fs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,15 @@ type AsyncType() =
8989
Async.RunSynchronously(computation, timeout = 1000) |> ignore
9090

9191
[<Test>]
92-
member this.AsyncSleepCancellation1() =
92+
[<TestCase("int32")>]
93+
[<TestCase("timespan")>]
94+
member this.AsyncSleepCancellation1(sleepType) =
9395
ignoreSynchCtx (fun () ->
94-
let computation = Async.Sleep(10000000)
96+
let computation =
97+
match sleepType with
98+
| "int32" -> Async.Sleep(10000000)
99+
| "timespan" -> Async.Sleep(10000000.0 |> TimeSpan.FromMilliseconds)
100+
| unknown -> raise (NotImplementedException(unknown))
95101
let result = ref ""
96102
use cts = new CancellationTokenSource()
97103
Async.StartWithContinuations(computation,
@@ -105,9 +111,15 @@ type AsyncType() =
105111
)
106112

107113
[<Test>]
108-
member this.AsyncSleepCancellation2() =
114+
[<TestCase("int32")>]
115+
[<TestCase("timespan")>]
116+
member this.AsyncSleepCancellation2(sleepType) =
109117
ignoreSynchCtx (fun () ->
110-
let computation = Async.Sleep(10)
118+
let computation =
119+
match sleepType with
120+
| "int32" -> Async.Sleep(10)
121+
| "timespan" -> Async.Sleep(10.0 |> TimeSpan.FromMilliseconds)
122+
| unknown -> raise (NotImplementedException(unknown))
111123
for i in 1..100 do
112124
let result = ref ""
113125
use completedEvent = new ManualResetEvent(false)
@@ -123,6 +135,36 @@ type AsyncType() =
123135
Assert.IsTrue(!result = "Cancel" || !result = "Ok")
124136
)
125137

138+
[<Test>]
139+
[<TestCase("int32")>]
140+
[<TestCase("timespan")>]
141+
member this.AsyncSleepThrowsOnNegativeDueTimes(sleepType) =
142+
async {
143+
try
144+
do! match sleepType with
145+
| "int32" -> Async.Sleep(-100)
146+
| "timespan" -> Async.Sleep(-100.0 |> TimeSpan.FromMilliseconds)
147+
| unknown -> raise (NotImplementedException(unknown))
148+
failwith "Expected ArgumentOutOfRangeException"
149+
with
150+
| :? ArgumentOutOfRangeException -> ()
151+
} |> Async.RunSynchronously
152+
153+
[<Test>]
154+
member this.AsyncSleepInfinitely() =
155+
ignoreSynchCtx (fun () ->
156+
let computation = Async.Sleep(System.Threading.Timeout.Infinite)
157+
let result = TaskCompletionSource()
158+
use cts = new CancellationTokenSource(TimeSpan.FromSeconds(1.0)) // there's a long way from 1 sec to infinity, but it'll have to do.
159+
Async.StartWithContinuations(computation,
160+
(fun _ -> result.TrySetResult("Ok") |> ignore),
161+
(fun _ -> result.TrySetResult("Exception") |> ignore),
162+
(fun _ -> result.TrySetResult("Cancel") |> ignore),
163+
cts.Token)
164+
let result = result.Task |> Async.AwaitTask |> Async.RunSynchronously
165+
Assert.AreEqual("Cancel", result)
166+
)
167+
126168
member private this.WaitASec (t:Task) =
127169
let result = t.Wait(TimeSpan(hours=0,minutes=0,seconds=1))
128170
Assert.IsTrue(result, "Task did not finish after waiting for a second.")

tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Mic
538538
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AwaitTask(System.Threading.Tasks.Task)
539539
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Ignore[T](Microsoft.FSharp.Control.FSharpAsync`1[T])
540540
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Sleep(Int32)
541+
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Sleep(System.TimeSpan)
541542
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToContext(System.Threading.SynchronizationContext)
542543
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToNewThread()
543544
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToThreadPool()

tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Mic
538538
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AwaitTask(System.Threading.Tasks.Task)
539539
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Ignore[T](Microsoft.FSharp.Control.FSharpAsync`1[T])
540540
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Sleep(Int32)
541+
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] Sleep(System.TimeSpan)
541542
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToContext(System.Threading.SynchronizationContext)
542543
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToNewThread()
543544
Microsoft.FSharp.Control.FSharpAsync: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] SwitchToThreadPool()

tests/fsharpqa/Source/Printing/SignatureWithOptionalArgs01.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ open Microsoft.FSharp.Control
1515

1616
type AsyncTimer(f, ?delay ) =
1717
let mutable does_again = true
18-
let mutable delay = delay
18+
let mutable delay: int option = delay
1919

2020
member t.Delay
2121
with get() = delay

0 commit comments

Comments
 (0)