diff --git a/src/ElectronNET.API/API/App.cs b/src/ElectronNET.API/API/App.cs index a1843031..0e92803c 100644 --- a/src/ElectronNET.API/API/App.cs +++ b/src/ElectronNET.API/API/App.cs @@ -427,7 +427,7 @@ public void Exit(int exitCode = 0) 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 4db0a0b7..86d870e2 100644 --- a/src/ElectronNET.API/Bridge/SocketIOFacade.cs +++ b/src/ElectronNET.API/Bridge/SocketIOFacade.cs @@ -8,10 +8,11 @@ namespace ElectronNET.API; using SocketIO.Serializer.SystemTextJson; using SocketIO = SocketIOClient.SocketIO; -internal class SocketIoFacade +internal class SocketIoFacade : IDisposable { private readonly SocketIO _socket; private readonly object _lockObj = new object(); + private bool _isDisposed; public SocketIoFacade(string uri) { @@ -27,6 +28,8 @@ public SocketIoFacade(string uri) public void Connect() { + this.CheckDisposed(); + _socket.OnError += (sender, e) => { Console.WriteLine($"BridgeConnector Error: {sender} {e}"); }; _socket.OnConnected += (_, _) => @@ -46,6 +49,8 @@ public void Connect() public void On(string eventName, Action action) { + this.CheckDisposed(); + lock (_lockObj) { _socket.On(eventName, _ => { Task.Run(action); }); @@ -54,6 +59,8 @@ public void On(string eventName, Action action) public void On(string eventName, Action action) { + this.CheckDisposed(); + lock (_lockObj) { _socket.On(eventName, response => @@ -66,6 +73,8 @@ public void On(string eventName, Action action) public void Once(string eventName, Action action) { + this.CheckDisposed(); + lock (_lockObj) { _socket.On(eventName, _ => @@ -78,6 +87,8 @@ public void Once(string eventName, Action action) public void Once(string eventName, Action action) { + this.CheckDisposed(); + lock (_lockObj) { _socket.On(eventName, (socketIoResponse) => @@ -90,6 +101,11 @@ public void Once(string eventName, Action action) public void Off(string eventName) { + if (_isDisposed) + { + return; + } + lock (_lockObj) { _socket.Off(eventName); @@ -98,11 +114,33 @@ public void Off(string eventName) 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); + } + } + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _isDisposed = true; + _socket.Dispose(); + } } - public void DisposeSocket() + private void CheckDisposed() { - _socket.Dispose(); + 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 23ca4d86..7e8be64b 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 StartCore() 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 1be7aa44..26d7d867 100644 --- a/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/BrowserWindowTests.cs @@ -266,9 +266,11 @@ public async Task BoundsChanged_event_fires_with_updated_bounds() 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 7afae016..6afdc2eb 100644 --- a/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs +++ b/src/ElectronNET.IntegrationTests/Tests/WebContentsTests.cs @@ -174,13 +174,15 @@ public async Task GetSetUserAgent_check() 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");