From 7a487d2ff9b07b7cdc918f4d4a3aec5fc3e7bd45 Mon Sep 17 00:00:00 2001 From: Rustam Sayfutdinov Date: Sat, 23 Apr 2022 09:45:30 +0300 Subject: [PATCH 01/10] Fix receiving and processing mailbox after Dispose --- src/FSharp.Core/mailbox.fs | 13 +++++- .../MailboxProcessorType.fs | 42 ++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/FSharp.Core/mailbox.fs b/src/FSharp.Core/mailbox.fs index 91c60d25cb..584fd1ee93 100644 --- a/src/FSharp.Core/mailbox.fs +++ b/src/FSharp.Core/mailbox.fs @@ -62,6 +62,7 @@ module AsyncHelpers = [] [] type Mailbox<'Msg>(cancellationSupported: bool) = + let mutable hasNotDisposed = true let mutable inboxStore = null let arrivals = Queue<'Msg>() let syncRoot = arrivals @@ -176,8 +177,9 @@ type Mailbox<'Msg>(cancellationSupported: bool) = member x.Post msg = lock syncRoot (fun () -> - // Add the message to the arrivals queue - arrivals.Enqueue msg + if hasNotDisposed then + // Add the message to the arrivals queue + arrivals.Enqueue msg // Cooperatively unblock any waiting reader. If there is no waiting // reader we just leave the message in the incoming queue @@ -332,6 +334,13 @@ type Mailbox<'Msg>(cancellationSupported: bool) = interface System.IDisposable with member _.Dispose() = + lock syncRoot (fun () -> + if isNotNull inboxStore then + inboxStore.Clear() + + arrivals.Clear() + hasNotDisposed <- false) + if isNotNull pulse then (pulse :> IDisposable).Dispose() diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs index 2a180783da..7fbeabcb5d 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs @@ -6,8 +6,9 @@ namespace FSharp.Core.UnitTests.Control open System -open Xunit open System.Threading +open System.Threading.Tasks +open Xunit type Message = | Increment of int @@ -302,6 +303,45 @@ type MailboxProcessorType() = finishedEv.Reset() |> ignore + [] + member this.``After dispose is called, mailbox should stop receiving and processing messages``() = task { + let mutable isSkip = false + let mutable actualSkipMessagesCount = 0 + let mutable actualMessagesCount = 0 + let sleepDueTime = 1000 + let expectedMessagesCount = 2 + let mb = + MailboxProcessor.Start(fun b -> + let rec loop() = + async { + match! b.Receive() with + | Increment _ -> + if isSkip then + actualSkipMessagesCount <- actualSkipMessagesCount + 1 + return! loop() + else + do! Async.Sleep sleepDueTime + if isSkip |> not then actualMessagesCount <- actualMessagesCount + 1 + return! loop() + | _ -> () + } + loop() + ) + let post() = Increment 1 |> mb.Post + + [1..4] |> Seq.iter (fun _ -> post()) + do! task { + do! Task.Delay (expectedMessagesCount * sleepDueTime + 500) + isSkip <- true + (mb :> IDisposable).Dispose() + post() + } + + Assert.Equal(expectedMessagesCount, actualMessagesCount) + Assert.Equal(0, actualSkipMessagesCount) + Assert.Equal(0, mb.CurrentQueueLength) + } + [] member this.Dispose() = From 0b5c088f3195d85615b774bab53ebafed76e78d2 Mon Sep 17 00:00:00 2001 From: Rustam Sayfutdinov Date: Thu, 31 Aug 2023 20:56:58 +0300 Subject: [PATCH 02/10] Refactor --- .../Microsoft.FSharp.Control/MailboxProcessorType.fs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs index 4097d9ed73..ac3c576b25 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs @@ -317,8 +317,9 @@ type MailboxProcessorType() = let mutable isSkip = false let mutable actualSkipMessagesCount = 0 let mutable actualMessagesCount = 0 - let sleepDueTime = 1000 + let sleepDueTime = 100 let expectedMessagesCount = 2 + use mre = new ManualResetEventSlim(false) let mb = MailboxProcessor.Start(fun b -> let rec loop() = @@ -330,7 +331,10 @@ type MailboxProcessorType() = return! loop() else do! Async.Sleep sleepDueTime - if isSkip |> not then actualMessagesCount <- actualMessagesCount + 1 + if not isSkip then + actualMessagesCount <- actualMessagesCount + 1 + if actualMessagesCount = expectedMessagesCount then mre.Set() + do! Async.Sleep sleepDueTime return! loop() | _ -> () } @@ -338,9 +342,9 @@ type MailboxProcessorType() = ) let post() = Increment 1 |> mb.Post - [1..4] |> Seq.iter (fun _ -> post()) + [1..4] |> Seq.iter (fun x -> post()) do! task { - do! Task.Delay (expectedMessagesCount * sleepDueTime + 500) + mre.Wait() isSkip <- true (mb :> IDisposable).Dispose() post() From 4ed050e3298c29cd7313ee55ccd44045bc667d96 Mon Sep 17 00:00:00 2001 From: Rustam Sayfutdinov Date: Fri, 1 Sep 2023 13:20:12 +0300 Subject: [PATCH 03/10] Refactoring --- src/FSharp.Core/mailbox.fs | 11 ++++++----- .../Microsoft.FSharp.Control/MailboxProcessorType.fs | 7 ++++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/FSharp.Core/mailbox.fs b/src/FSharp.Core/mailbox.fs index ac6388202f..df8a35f37e 100644 --- a/src/FSharp.Core/mailbox.fs +++ b/src/FSharp.Core/mailbox.fs @@ -61,7 +61,7 @@ module AsyncHelpers = [] [] type Mailbox<'Msg>(cancellationSupported: bool) = - let mutable hasNotDisposed = true + let mutable isDisposed = false let mutable inboxStore = null let arrivals = Queue<'Msg>() let syncRoot = arrivals @@ -175,10 +175,11 @@ type Mailbox<'Msg>(cancellationSupported: bool) = member x.Post msg = lock syncRoot (fun () -> + if isDisposed then + raise (ObjectDisposedException(nameof Mailbox)) - if hasNotDisposed then - // Add the message to the arrivals queue - arrivals.Enqueue msg + // Add the message to the arrivals queue + arrivals.Enqueue msg // Cooperatively unblock any waiting reader. If there is no waiting // reader we just leave the message in the incoming queue @@ -338,7 +339,7 @@ type Mailbox<'Msg>(cancellationSupported: bool) = inboxStore.Clear() arrivals.Clear() - hasNotDisposed <- false) + isDisposed <- true) if isNotNull pulse then (pulse :> IDisposable).Dispose() diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs index ac3c576b25..8d6514462c 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs @@ -347,7 +347,12 @@ type MailboxProcessorType() = mre.Wait() isSkip <- true (mb :> IDisposable).Dispose() - post() + try + post() + Assert.Fail() + with + | :? ObjectDisposedException -> () + | ex -> Assert.Fail(ex.Message) } Assert.Equal(expectedMessagesCount, actualMessagesCount) From 583fa7344659e77fecb5ccfb00158279417cd7dc Mon Sep 17 00:00:00 2001 From: Rustam Sayfutdinov Date: Sat, 2 Sep 2023 14:12:11 +0300 Subject: [PATCH 04/10] refactor --- .../Microsoft.FSharp.Control/MailboxProcessorType.fs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs index 8d6514462c..94c91b8268 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs @@ -347,12 +347,7 @@ type MailboxProcessorType() = mre.Wait() isSkip <- true (mb :> IDisposable).Dispose() - try - post() - Assert.Fail() - with - | :? ObjectDisposedException -> () - | ex -> Assert.Fail(ex.Message) + Assert.Throws(fun _ -> post()) |> ignore } Assert.Equal(expectedMessagesCount, actualMessagesCount) From 3f2af51da1660ab1fc924adc896b6d1ab46937ad Mon Sep 17 00:00:00 2001 From: Rustam Sayfutdinov Date: Sun, 10 Mar 2024 11:23:48 +0300 Subject: [PATCH 05/10] Add option to throw exception --- docs/release-notes/.FSharp.Core/8.0.300.md | 2 + src/FSharp.Core/mailbox.fs | 37 ++++++++--- src/FSharp.Core/mailbox.fsi | 61 +++++++++++++++++++ .../MailboxProcessorType.fs | 44 +++++++++++++ 4 files changed, 137 insertions(+), 7 deletions(-) diff --git a/docs/release-notes/.FSharp.Core/8.0.300.md b/docs/release-notes/.FSharp.Core/8.0.300.md index 7c3911ae98..a7437343a9 100644 --- a/docs/release-notes/.FSharp.Core/8.0.300.md +++ b/docs/release-notes/.FSharp.Core/8.0.300.md @@ -2,7 +2,9 @@ * Minor tweaks to inline specifications to support Visibility PR ([PR #15484](https://github.com/dotnet/fsharp/pull/15484), [#PR 16427](https://github.com/dotnet/fsharp/pull/15484) * Optimize equality in generic contexts. ([PR #16615](https://github.com/dotnet/fsharp/pull/16615)) +* Add ctor for MailboxProcessor with a flag denotes will be thrown exception when `Post` is called after MailboxProcessor" disposed. ([PR #13036](https://github.com/dotnet/fsharp/pull/13036)) ### Fixed * Preserve original stack traces in resumable state machines generated code if available. ([PR #16568](https://github.com/dotnet/fsharp/pull/16568)) +* Fix receiving and processing mailbox after Dispose. ([PR #13036](https://github.com/dotnet/fsharp/pull/13036)) diff --git a/src/FSharp.Core/mailbox.fs b/src/FSharp.Core/mailbox.fs index 73bbc00426..a743afc3f4 100644 --- a/src/FSharp.Core/mailbox.fs +++ b/src/FSharp.Core/mailbox.fs @@ -60,7 +60,7 @@ module AsyncHelpers = [] [] -type Mailbox<'Msg>(cancellationSupported: bool) = +type Mailbox<'Msg>(cancellationSupported: bool, isThrowExceptionAfterDisposed: bool) = let mutable isDisposed = false let mutable inboxStore = null let arrivals = Queue<'Msg>() @@ -176,10 +176,11 @@ type Mailbox<'Msg>(cancellationSupported: bool) = member x.Post msg = lock syncRoot (fun () -> if isDisposed then - raise (ObjectDisposedException(nameof Mailbox)) - - // Add the message to the arrivals queue - arrivals.Enqueue msg + if isThrowExceptionAfterDisposed then + raise (ObjectDisposedException(nameof Mailbox)) + else + // Add the message to the arrivals queue + arrivals.Enqueue msg // Cooperatively unblock any waiting reader. If there is no waiting // reader we just leave the message in the incoming queue @@ -357,15 +358,23 @@ type AsyncReplyChannel<'Reply>(replyf: 'Reply -> unit) = [] [] [] -type MailboxProcessor<'Msg>(body, ?cancellationToken) = +type MailboxProcessor<'Msg>(body, isThrowExceptionAfterDisposed, ?cancellationToken) = let cancellationSupported = cancellationToken.IsSome let cancellationToken = defaultArg cancellationToken Async.DefaultCancellationToken - let mailbox = new Mailbox<'Msg>(cancellationSupported) + + let mailbox = + new Mailbox<'Msg>(cancellationSupported, isThrowExceptionAfterDisposed) + let mutable defaultTimeout = Threading.Timeout.Infinite let mutable started = false let errorEvent = new Event() + new(body, ?cancellationToken: CancellationToken) = + match cancellationToken with + | None -> new MailboxProcessor<'Msg>(body, false) + | Some ct -> new MailboxProcessor<'Msg>(body, false, ct) + member _.CurrentQueueLength = mailbox.CurrentQueueLength // nb. unprotected access gives an approximation of the queue length member _.DefaultTimeout @@ -516,9 +525,23 @@ type MailboxProcessor<'Msg>(body, ?cancellationToken) = mailboxProcessor.Start() mailboxProcessor + static member Start(body, isThrowExceptionAfterDisposed, ?cancellationToken) = + let mailboxProcessor = + new MailboxProcessor<'Msg>(body, isThrowExceptionAfterDisposed, ?cancellationToken = cancellationToken) + + mailboxProcessor.Start() + mailboxProcessor + static member StartImmediate(body, ?cancellationToken) = let mailboxProcessor = new MailboxProcessor<'Msg>(body, ?cancellationToken = cancellationToken) mailboxProcessor.StartImmediate() mailboxProcessor + + static member StartImmediate(body, isThrowExceptionAfterDisposed, ?cancellationToken) = + let mailboxProcessor = + new MailboxProcessor<'Msg>(body, isThrowExceptionAfterDisposed, ?cancellationToken = cancellationToken) + + mailboxProcessor.StartImmediate() + mailboxProcessor diff --git a/src/FSharp.Core/mailbox.fsi b/src/FSharp.Core/mailbox.fsi index ae245d8ace..6b0ad7bc54 100644 --- a/src/FSharp.Core/mailbox.fsi +++ b/src/FSharp.Core/mailbox.fsi @@ -43,6 +43,27 @@ type MailboxProcessor<'Msg> = /// new: body: (MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> + /// Creates an agent. The body function is used to generate the asynchronous + /// computation executed by the agent. This function is not executed until + /// Start is called. + /// + /// The function to produce an asynchronous computation that will be executed + /// as the read loop for the MailboxProcessor when Start is called. + /// A flag denotes will be thrown exception + /// when is called + /// after disposed. + /// An optional cancellation token for the body. + /// Defaults to Async.DefaultCancellationToken. + /// + /// The created MailboxProcessor. + /// + /// + new: + body: (MailboxProcessor<'Msg> -> Async) * + isThrowExceptionAfterDisposed: bool * + ?cancellationToken: CancellationToken -> + MailboxProcessor<'Msg> + /// Creates and starts an agent. The body function is used to generate the asynchronous /// computation executed by the agent. /// @@ -57,6 +78,26 @@ type MailboxProcessor<'Msg> = static member Start: body: (MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> + /// Creates and starts an agent. The body function is used to generate the asynchronous + /// computation executed by the agent. + /// + /// The function to produce an asynchronous computation that will be executed + /// as the read loop for the MailboxProcessor when Start is called. + /// A flag denotes will be thrown exception + /// when is called + /// after disposed. + /// An optional cancellation token for the body. + /// Defaults to Async.DefaultCancellationToken. + /// + /// The created MailboxProcessor. + /// + /// + static member Start: + body: (MailboxProcessor<'Msg> -> Async) * + isThrowExceptionAfterDisposed: bool * + ?cancellationToken: CancellationToken -> + MailboxProcessor<'Msg> + /// Creates and starts an agent immediately on the current operating system thread. The body /// function is used to generate the asynchronous computation executed by the agent. /// @@ -71,6 +112,26 @@ type MailboxProcessor<'Msg> = static member StartImmediate: body: (MailboxProcessor<'Msg> -> Async) * ?cancellationToken: CancellationToken -> MailboxProcessor<'Msg> + /// Creates and starts an agent immediately on the current operating system thread. The body + /// function is used to generate the asynchronous computation executed by the agent. + /// + /// The function to produce an asynchronous computation that will be executed + /// as the read loop for the MailboxProcessor when StartImmediately is called. + /// A flag denotes will be thrown exception + /// when is called + /// after disposed. + /// An optional cancellation token for the body. + /// Defaults to Async.DefaultCancellationToken. + /// + /// The created MailboxProcessor. + /// + /// + static member StartImmediate: + body: (MailboxProcessor<'Msg> -> Async) * + isThrowExceptionAfterDisposed: bool * + ?cancellationToken: CancellationToken -> + MailboxProcessor<'Msg> + /// Posts a message to the message queue of the MailboxProcessor, asynchronously. /// /// The message to post. diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs index 94c91b8268..8c686a8a21 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs +++ b/tests/FSharp.Core.UnitTests/FSharp.Core/Microsoft.FSharp.Control/MailboxProcessorType.fs @@ -342,6 +342,50 @@ type MailboxProcessorType() = ) let post() = Increment 1 |> mb.Post + [1..4] |> Seq.iter (fun x -> post()) + do! task { + mre.Wait() + isSkip <- true + (mb :> IDisposable).Dispose() + post() + } + + Assert.Equal(expectedMessagesCount, actualMessagesCount) + Assert.Equal(0, actualSkipMessagesCount) + Assert.Equal(0, mb.CurrentQueueLength) + } + + [] + member this.``After dispose is called, mailbox should stop receiving and processing messages with exception``() = task { + let mutable isSkip = false + let mutable actualSkipMessagesCount = 0 + let mutable actualMessagesCount = 0 + let sleepDueTime = 100 + let expectedMessagesCount = 2 + use mre = new ManualResetEventSlim(false) + let mb = + MailboxProcessor.Start((fun b -> + let rec loop() = + async { + match! b.Receive() with + | Increment _ -> + if isSkip then + actualSkipMessagesCount <- actualSkipMessagesCount + 1 + return! loop() + else + do! Async.Sleep sleepDueTime + if not isSkip then + actualMessagesCount <- actualMessagesCount + 1 + if actualMessagesCount = expectedMessagesCount then mre.Set() + do! Async.Sleep sleepDueTime + return! loop() + | _ -> () + } + loop()), + true + ) + let post() = Increment 1 |> mb.Post + [1..4] |> Seq.iter (fun x -> post()) do! task { mre.Wait() From 4a70a4acd2b7ef7dc90a0c449d5950c9fff44ee9 Mon Sep 17 00:00:00 2001 From: Petr Date: Mon, 11 Mar 2024 12:02:15 +0100 Subject: [PATCH 06/10] Update 8.0.300.md --- docs/release-notes/.FSharp.Core/8.0.300.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Core/8.0.300.md b/docs/release-notes/.FSharp.Core/8.0.300.md index a7437343a9..8914fde19a 100644 --- a/docs/release-notes/.FSharp.Core/8.0.300.md +++ b/docs/release-notes/.FSharp.Core/8.0.300.md @@ -2,7 +2,7 @@ * Minor tweaks to inline specifications to support Visibility PR ([PR #15484](https://github.com/dotnet/fsharp/pull/15484), [#PR 16427](https://github.com/dotnet/fsharp/pull/15484) * Optimize equality in generic contexts. ([PR #16615](https://github.com/dotnet/fsharp/pull/16615)) -* Add ctor for MailboxProcessor with a flag denotes will be thrown exception when `Post` is called after MailboxProcessor" disposed. ([PR #13036](https://github.com/dotnet/fsharp/pull/13036)) +* Add a constructor for `MailboxProcessor` with a flag denoting that an exception will be thrown when `Post` is called after the `MailboxProcessor` has been disposed. ([PR #13036](https://github.com/dotnet/fsharp/pull/13036)) ### Fixed From 108a3ec685b49c60305f14e4299350dd3b8a3444 Mon Sep 17 00:00:00 2001 From: Petr Date: Mon, 11 Mar 2024 12:05:11 +0100 Subject: [PATCH 07/10] Update mailbox.fsi --- src/FSharp.Core/mailbox.fsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FSharp.Core/mailbox.fsi b/src/FSharp.Core/mailbox.fsi index 6b0ad7bc54..740ab77080 100644 --- a/src/FSharp.Core/mailbox.fsi +++ b/src/FSharp.Core/mailbox.fsi @@ -49,9 +49,9 @@ type MailboxProcessor<'Msg> = /// /// The function to produce an asynchronous computation that will be executed /// as the read loop for the MailboxProcessor when Start is called. - /// A flag denotes will be thrown exception + /// A flag denoting that an exception will be thrown /// when is called - /// after disposed. + /// after has been disposed. /// An optional cancellation token for the body. /// Defaults to Async.DefaultCancellationToken. /// @@ -83,9 +83,9 @@ type MailboxProcessor<'Msg> = /// /// The function to produce an asynchronous computation that will be executed /// as the read loop for the MailboxProcessor when Start is called. - /// A flag denotes will be thrown exception + /// A flag denoting that an exception will be thrown /// when is called - /// after disposed. + /// after has been disposed. /// An optional cancellation token for the body. /// Defaults to Async.DefaultCancellationToken. /// From 6341629728717b62fc074fae1a46aa9ad74e6fb7 Mon Sep 17 00:00:00 2001 From: Petr Date: Tue, 19 Mar 2024 16:02:49 +0100 Subject: [PATCH 08/10] baselines --- .../FSharp.Core.SurfaceArea.netstandard21.debug.bsl | 3 +++ .../FSharp.Core.SurfaceArea.netstandard21.release.bsl | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl index adc21566d8..9efe28bb17 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.debug.bsl @@ -671,10 +671,13 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose() Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl index eba99c47de..eefd052ca1 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard21.release.bsl @@ -671,10 +671,13 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose() Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) From d65a15ac85af9dec8476885f45922e475236f484 Mon Sep 17 00:00:00 2001 From: Petr Date: Tue, 19 Mar 2024 19:29:44 +0100 Subject: [PATCH 09/10] Update Tests.LanguageService.Completion.fs --- .../LegacyLanguageService/Tests.LanguageService.Completion.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs index a88ce83e90..9cc1ed259d 100644 --- a/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs +++ b/vsintegration/tests/UnitTests/LegacyLanguageService/Tests.LanguageService.Completion.fs @@ -4392,7 +4392,7 @@ let x = query { for bbbb in abbbbc(*D0*) do // Get description for Expr.Var let (CompletionItem(_, _, _, descrFunc, _)) = completions |> Array.find (fun (CompletionItem(name, _, _, _, _)) -> name = "Start") let occurrences = this.CountMethodOccurrences(descrFunc(), "Start") - AssertEqualWithMessage(1, occurrences, sprintf "Found wrong number of overloads for 'MailboxProcessor.Start'. Found %A." completions) + AssertEqualWithMessage(2, occurrences, sprintf "Found wrong number of overloads for 'MailboxProcessor.Start'. Found %A." completions) [] member public this.``WithinMatchClause.Bug1603``() = From f0ad6b98c99faf1b11bb4ff96dd6722803e97645 Mon Sep 17 00:00:00 2001 From: Petr Date: Wed, 20 Mar 2024 13:21:33 +0100 Subject: [PATCH 10/10] bsl --- .../FSharp.Core.SurfaceArea.netstandard20.debug.bsl | 3 +++ .../FSharp.Core.SurfaceArea.netstandard20.release.bsl | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl index e156eba459..f50a8c6230 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.debug.bsl @@ -671,10 +671,13 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose() Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg) diff --git a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl index b4cb84825d..964805cfa2 100644 --- a/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Core.UnitTests/FSharp.Core.SurfaceArea.netstandard20.release.bsl @@ -671,10 +671,13 @@ Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Contro Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[TReply] PostAndAsyncReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpAsync`1[T] Scan[T](Microsoft.FSharp.Core.FSharpFunc`2[TMsg,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpHandler`1[System.Exception] Error +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] Start(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg] StartImmediate(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Microsoft.FSharp.Core.FSharpOption`1[TReply] TryPostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: TReply PostAndReply[TReply](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpAsyncReplyChannel`1[TReply],TMsg], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Boolean, Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg],Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit]], Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Dispose() Microsoft.FSharp.Control.FSharpMailboxProcessor`1[TMsg]: Void Post(TMsg)