diff --git a/src/Compiler/Interactive/FSharpInteractiveServer.fs b/src/Compiler/Interactive/FSharpInteractiveServer.fs index a440175622f..c5ff7f1346a 100644 --- a/src/Compiler/Interactive/FSharpInteractiveServer.fs +++ b/src/Compiler/Interactive/FSharpInteractiveServer.fs @@ -25,41 +25,44 @@ module CtrlBreakHandlers = // Exceptions percolate to callsite, IO exceptions must be handled by caller // Should be run on a new thread member this.Run() : unit = - let service = Some(new NamedPipeServerStream(channelName, PipeDirection.In)) + let service = new NamedPipeServerStream(channelName, PipeDirection.In) - match service with - | Some service -> - // Wait for a client to connect - service.WaitForConnection() - use stream = new StreamReader(service) + // Wait for a client to connect + service.WaitForConnection() + use stream = new StreamReader(service) - try - while not (stream.EndOfStream) do - let line = stream.ReadLine() - - if line = interuptCommand then - this.Interrupt() - finally - stream.Close() - service.Close() - | None -> () + try + while not (stream.EndOfStream) do + let line = stream.ReadLine() + + if line = interuptCommand then + this.Interrupt() + finally + stream.Close() + service.Close() type public CtrlBreakClient(channelName: string) = - let mutable service: NamedPipeClientStream option = None + let mutable service: NamedPipeClientStream option = Some(new NamedPipeClientStream(".", channelName, PipeDirection.Out)) member this.Interrupt() = match service with | None -> () - | Some service -> + | Some client -> try - if not (service.IsConnected) then - service.Connect(connectionTimeout) + if not (client.IsConnected) then + client.Connect(connectionTimeout) with _ -> () - service.Write(lineInteruptCommand, 0, lineInteruptCommand.Length) - service.Flush() + client.Write(lineInteruptCommand, 0, lineInteruptCommand.Length) + client.Flush() + + interface IDisposable with + member _.Dispose() = + match service with + | None -> () + | Some client -> + client.Dispose() + service <- None - member _.Start() = - service <- Some(new NamedPipeClientStream(".", channelName, PipeDirection.Out)) diff --git a/src/Compiler/Interactive/FSharpInteractiveServer.fsi b/src/Compiler/Interactive/FSharpInteractiveServer.fsi index 85b4e7bacd4..2e3359dc01d 100644 --- a/src/Compiler/Interactive/FSharpInteractiveServer.fsi +++ b/src/Compiler/Interactive/FSharpInteractiveServer.fsi @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. namespace FSharp.Compiler.Interactive +open System module CtrlBreakHandlers = @@ -12,8 +13,9 @@ module CtrlBreakHandlers = member Run: unit -> unit type public CtrlBreakClient = + new: channelName: string -> CtrlBreakClient member Interrupt: unit -> unit - member Start: unit -> unit + interface IDisposable \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/sessions.fs b/vsintegration/src/FSharp.VS.FSI/sessions.fs index fd508932975..c552c0eda41 100644 --- a/vsintegration/src/FSharp.VS.FSI/sessions.fs +++ b/vsintegration/src/FSharp.VS.FSI/sessions.fs @@ -352,11 +352,9 @@ type FsiSession(sourceFile: string) = do cmdProcess.EnableRaisingEvents <- true - let clientConnection = + let client = try - let server = CtrlBreakClient(channelName) - server.Start() - Some server + new CtrlBreakClient(channelName) with e -> raise (SessionError (VFSIstrings.SR.exceptionRaisedWhenCreatingRemotingClient(e.ToString()))) /// interrupt timeout in miliseconds @@ -364,12 +362,9 @@ type FsiSession(sourceFile: string) = // Create session object member _.Interrupt() = - match clientConnection with - | None -> false - | Some client -> - match timeoutApp "VFSI interrupt" interruptTimeoutMS (fun () -> client.Interrupt()) () with - | Some () -> true - | None -> false + match timeoutApp "VFSI interrupt" interruptTimeoutMS (fun () -> client.Interrupt()) () with + | Some () -> true + | None -> false member _.SendInput (str: string) = inputQueue.Post(str) @@ -381,7 +376,7 @@ type FsiSession(sourceFile: string) = member _.Alive = not cmdProcess.HasExited - member _.SupportsInterrupt = not cmdProcess.HasExited && clientConnection.IsSome + member _.SupportsInterrupt = not cmdProcess.HasExited member _.ProcessID = // When using .NET Core, allow up to 2 seconds to allow detection of process ID