diff --git a/src/ElectronNET.API/API/App.cs b/src/ElectronNET.API/API/App.cs index a184303..0e92803 100644 --- a/src/ElectronNET.API/API/App.cs +++ b/src/ElectronNET.API/API/App.cs @@ -427,7 +427,7 @@ namespace ElectronNET.API public void DisposeSocket() { - BridgeConnector.Socket.DisposeSocket(); + BridgeConnector.Socket.Dispose(); } /// diff --git a/src/ElectronNET.API/Bridge/SocketIOFacade.cs b/src/ElectronNET.API/Bridge/SocketIOFacade.cs index 58f0fef..96d5454 100644 --- a/src/ElectronNET.API/Bridge/SocketIOFacade.cs +++ b/src/ElectronNET.API/Bridge/SocketIOFacade.cs @@ -9,10 +9,11 @@ using ElectronNET.API.Serialization; using SocketIO.Serializer.SystemTextJson; using SocketIO = SocketIOClient.SocketIO; -internal class SocketIoFacade : IFacade +internal class SocketIoFacade : IFacade, IDisposable { private readonly SocketIO _socket; private readonly object _lockObj = new object(); + private bool _isDisposed; public SocketIoFacade(string uri) { @@ -28,6 +29,8 @@ internal class SocketIoFacade : IFacade public void Connect() { + this.CheckDisposed(); + _socket.OnError += (sender, e) => { Console.WriteLine($"BridgeConnector Error: {sender} {e}"); }; _socket.OnConnected += (_, _) => @@ -47,6 +50,8 @@ internal class SocketIoFacade : IFacade public void On(string eventName, Action action) { + this.CheckDisposed(); + lock (_lockObj) { _socket.On(eventName, _ => { Task.Run(action); }); @@ -55,6 +60,8 @@ internal class SocketIoFacade : IFacade public void On(string eventName, Action action) { + this.CheckDisposed(); + lock (_lockObj) { _socket.On(eventName, response => @@ -67,6 +74,8 @@ internal class SocketIoFacade : IFacade public void Once(string eventName, Action action) { + this.CheckDisposed(); + lock (_lockObj) { _socket.On(eventName, _ => @@ -79,6 +88,8 @@ internal class SocketIoFacade : IFacade public void Once(string eventName, Action action) { + this.CheckDisposed(); + lock (_lockObj) { _socket.On(eventName, (socketIoResponse) => @@ -91,6 +102,11 @@ internal class SocketIoFacade : IFacade public void Off(string eventName) { + if (_isDisposed) + { + return; + } + lock (_lockObj) { _socket.Off(eventName); @@ -99,11 +115,33 @@ internal class SocketIoFacade : IFacade public async Task Emit(string eventName, params object[] args) { - await _socket.EmitAsync(eventName, args).ConfigureAwait(false); + if (!_isDisposed) + { + await _socket.EmitAsync(eventName, args).ConfigureAwait(false); + } } - public void DisposeSocket() + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public void Dispose() { - _socket.Dispose(); + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _isDisposed = true; + _socket.Dispose(); + } + } + + private void CheckDisposed() + { + if (this._isDisposed) + { + throw new ObjectDisposedException(nameof(SocketIoFacade)); + } } } \ No newline at end of file diff --git a/src/ElectronNET.API/Runtime/Services/SocketBridge/SocketBridgeService.cs b/src/ElectronNET.API/Runtime/Services/SocketBridge/SocketBridgeService.cs index 23ca4d8..7e8be64 100644 --- a/src/ElectronNET.API/Runtime/Services/SocketBridge/SocketBridgeService.cs +++ b/src/ElectronNET.API/Runtime/Services/SocketBridge/SocketBridgeService.cs @@ -33,7 +33,7 @@ protected override Task StopCore() { - this.socket.DisposeSocket(); + this.socket.Dispose(); return Task.CompletedTask; } diff --git a/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs b/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs index 1be7aa4..26d7d86 100644 --- a/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs @@ -266,9 +266,11 @@ namespace ElectronNET.IntegrationTests.Tests try { window = await Electron.WindowManager.CreateWindowAsync( - new BrowserWindowOptions { Show = false, Width = 300, Height = 200 }, + new BrowserWindowOptions { Show = true, Width = 300, Height = 200 }, "about:blank"); + await Task.Delay(5.seconds()); + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); window.OnBoundsChanged += bounds => tcs.TrySetResult(bounds); diff --git a/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs b/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs index 7afae01..6afdc2e 100644 --- a/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs @@ -174,13 +174,15 @@ namespace ElectronNET.IntegrationTests.Tests try { + await Task.Delay(1.seconds()); + window = await Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions { Show = true }, "about:blank"); - await Task.Delay(3.seconds()); + await Task.Delay(5.seconds()); window.WebContents.SetUserAgent("MyUserAgent/1.0"); - await Task.Delay(1.seconds()); + await Task.Delay(2.seconds()); var ok = await window.WebContents.GetUserAgentAsync(); ok.Should().Be("MyUserAgent/1.0"); diff --git a/src/ElectronNET.sln b/src/ElectronNET.sln index 7eb1d9f..1ecd4e8 100644 --- a/src/ElectronNET.sln +++ b/src/ElectronNET.sln @@ -22,7 +22,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "!Config", "!Config", "{02EA ProjectSection(SolutionItems) = preProject ..\Changelog.md = ..\Changelog.md common.props = common.props - global.json = global.json + ..\global.json = ..\global.json ..\NuGet.config = ..\NuGet.config ..\publish.cmd = ..\publish.cmd ..\README.md = ..\README.md