diff --git a/ElectronNET.API/App.cs b/ElectronNET.API/App.cs
index 69d8722c..3f64017f 100644
--- a/ElectronNET.API/App.cs
+++ b/ElectronNET.API/App.cs
@@ -1,4 +1,6 @@
 using ElectronNET.API.Entities;
+using ElectronNET.API.Hubs;
+using Microsoft.AspNetCore.SignalR;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using Newtonsoft.Json.Serialization;
@@ -7,6 +9,7 @@
 using System.Threading;
 using System.Threading.Tasks;
 using ElectronNET.API.Extensions;
+using System.Runtime.Versioning;
 
 namespace ElectronNET.API
 {
@@ -15,6 +18,56 @@ namespace ElectronNET.API
     /// 
     public sealed class App
     {
+        /// 
+        /// Emitted when the user clicks on the dock on Mac
+        /// 
+        /// 
+        [SupportedOSPlatform("macos")]
+        public event Action Activate
+        {
+            add
+            {
+                _appActivate += value;
+            }
+            remove
+            {
+                _appActivate -= value;
+            }
+        }
+
+        public void TriggerOnActivate()
+        {
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+            {
+                _appActivate();
+            }
+        }
+
+        private event Action _appActivate;
+
+        /// 
+        /// Emitted on the first instance when the user opens a second instance of the app, and the app is single instance
+        /// 
+        /// 
+        public event Action ActivateFromSecondInstance
+        {
+            add
+            {
+                _appActivateFromSecondInstance += value;
+            }
+            remove
+            {
+                _appActivateFromSecondInstance -= value;
+            }
+        }
+
+        public void TriggerOnAppActivateFromSecondInstance(string[] args)
+        {
+            _appActivateFromSecondInstance(args);
+        }
+
+        private event Action _appActivateFromSecondInstance;
+
         /// 
         /// Emitted when all windows have been closed.
         /// 
@@ -30,24 +83,21 @@ public event Action WindowAllClosed
             {
                 if (_windowAllClosed == null)
                 {
-                    BridgeConnector.Socket.On("app-window-all-closed" + GetHashCode(), () =>
-                    {
-                        if (!Electron.WindowManager.IsQuitOnWindowAllClosed || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
-                        {
-                            _windowAllClosed();
-                        }
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-window-all-closed-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-window-all-closed-event", GetHashCode());
                 }
                 _windowAllClosed += value;
             }
             remove
             {
                 _windowAllClosed -= value;
+            }
+        }
 
-                if(_windowAllClosed == null)
-                    BridgeConnector.Socket.Off("app-window-all-closed" + GetHashCode());
+        public void TriggerOnWindowAllClosed()
+        {
+            if (!Electron.WindowManager.IsQuitOnWindowAllClosed || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+            {
+                _windowAllClosed();
             }
         }
 
@@ -67,60 +117,58 @@ public event Func BeforeQuit
             {
                 if (_beforeQuit == null)
                 {
-                    BridgeConnector.Socket.On("app-before-quit" + GetHashCode(), async () =>
-                    {
-                        await _beforeQuit(new QuitEventArgs());
-
-                        if (_preventQuit)
-                        {
-                            _preventQuit = false;
-                        }
-                        else
-                        {
-                            if (_willQuit == null && _quitting == null)
-                            {
-                                Exit();
-                            }
-                            else if (_willQuit != null)
-                            {
-                                await _willQuit(new QuitEventArgs());
-
-                                if (_preventQuit)
-                                {
-                                    _preventQuit = false;
-                                }
-                                else
-                                {
-                                    if (_quitting == null)
-                                    {
-                                        Exit();
-                                    }
-                                    else
-                                    {
-                                        await _quitting();
-                                        Exit();
-                                    }
-                                }
-                            }
-                            else if (_quitting != null)
-                            {
-                                await _quitting();
-                                Exit();
-                            }
-                        }
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-before-quit-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-before-quit-event", GetHashCode());
                 }
                 _beforeQuit += value;
             }
             remove
             {
                 _beforeQuit -= value;
+            }
+        }
 
-                if (_beforeQuit == null)
-                    BridgeConnector.Socket.Off("app-before-quit" + GetHashCode());
+        public async Task TriggerOnBeforeQuit(QuitEventArgs quitEventArgs)
+        {
+            await _beforeQuit(new QuitEventArgs());
+
+            if (_preventQuit)
+            {
+                _preventQuit = false;
+            }
+            else
+            {
+                if (_willQuit == null && _quitting == null)
+                {
+                    Exit();
+                }
+                else if (_willQuit != null)
+                {
+                    await _willQuit(new QuitEventArgs());
+
+                    if (_preventQuit)
+                    {
+                        _preventQuit = false;
+                    }
+                    else
+                    {
+                        if (_quitting == null)
+                        {
+                            Exit();
+                        }
+                        else
+                        {
+                            await _quitting();
+                            Exit();
+                        }
+                    }
+                }
+                else if (_quitting != null)
+                {
+                    await _quitting();
+                    Exit();
+                }
             }
+            _beforeQuit(quitEventArgs);
         }
 
         private event Func _beforeQuit;
@@ -139,39 +187,37 @@ public event Func WillQuit
             {
                 if (_willQuit == null)
                 {
-                    BridgeConnector.Socket.On("app-will-quit" + GetHashCode(), async () =>
-                    {
-                        await _willQuit(new QuitEventArgs());
-
-                        if (_preventQuit)
-                        {
-                            _preventQuit = false;
-                        }
-                        else
-                        {
-                            if (_quitting == null)
-                            {
-                                Exit();
-                            }
-                            else
-                            {
-                                await _quitting();
-                                Exit();
-                            }
-                        }
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-will-quit-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-will-quit-event", GetHashCode());
                 }
                 _willQuit += value;
             }
             remove
             {
                 _willQuit -= value;
+            }
+        }
 
-                if (_willQuit == null)
-                    BridgeConnector.Socket.Off("app-will-quit" + GetHashCode());
+        public async Task TriggerOnWillQuit(QuitEventArgs quitEventArgs)
+        {
+            await _willQuit(new QuitEventArgs());
+
+            if (_preventQuit)
+            {
+                _preventQuit = false;
             }
+            else
+            {
+                if (_quitting == null)
+                {
+                    Exit();
+                }
+                else
+                {
+                    await _quitting();
+                    Exit();
+                }
+            }
+            _willQuit(quitEventArgs);
         }
 
         private event Func _willQuit;
@@ -187,26 +233,25 @@ public event Func Quitting
             {
                 if (_quitting == null)
                 {
-                    BridgeConnector.Socket.On("app-will-quit" + GetHashCode() + "quitting", async () =>
-                    {
-                        if(_willQuit == null)
-                        {
-                            await _quitting();
-                            Exit();
-                        }
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-will-quit-event", GetHashCode() + "quitting");
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-will-quit-event", GetHashCode());
                 }
                 _quitting += value;
             }
             remove
             {
                 _quitting -= value;
+            }
+        }
 
-                if (_quitting == null)
-                    BridgeConnector.Socket.Off("app-will-quit" + GetHashCode() + "quitting");
+        public async Task TriggerOnQuitting()
+        {
+            if (_willQuit == null)
+            {
+                await _quitting();
+                Exit();
             }
+
+            _quitting();
         }
 
         private event Func _quitting;
@@ -220,24 +265,21 @@ public event Action BrowserWindowBlur
             {
                 if (_browserWindowBlur == null)
                 {
-                    BridgeConnector.Socket.On("app-browser-window-blur" + GetHashCode(), () =>
-                    {
-                        _browserWindowBlur();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-browser-window-blur-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-browser-window-blur-event", GetHashCode());
                 }
                 _browserWindowBlur += value;
             }
             remove
             {
                 _browserWindowBlur -= value;
-
-                if (_browserWindowBlur == null)
-                    BridgeConnector.Socket.Off("app-browser-window-blur" + GetHashCode());
             }
         }
 
+        public void TriggerOnBrowserWindowBlur()
+        {
+            _browserWindowBlur();
+        }
+
         private event Action _browserWindowBlur;
 
         /// 
@@ -249,24 +291,21 @@ public event Action BrowserWindowFocus
             {
                 if (_browserWindowFocus == null)
                 {
-                    BridgeConnector.Socket.On("app-browser-window-focus" + GetHashCode(), () =>
-                    {
-                        _browserWindowFocus();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-browser-window-focus-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-browser-window-focus-event", GetHashCode());
                 }
                 _browserWindowFocus += value;
             }
             remove
             {
                 _browserWindowFocus -= value;
-
-                if (_browserWindowFocus == null)
-                    BridgeConnector.Socket.Off("app-browser-window-focus" + GetHashCode());
             }
         }
 
+        public void TriggerOnBrowserWindowFocus()
+        {
+            _browserWindowFocus();
+        }
+
         private event Action _browserWindowFocus;
 
         /// 
@@ -278,24 +317,21 @@ public event Action BrowserWindowCreated
             {
                 if (_browserWindowCreated == null)
                 {
-                    BridgeConnector.Socket.On("app-browser-window-created" + GetHashCode(), () =>
-                    {
-                        _browserWindowCreated();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-browser-window-created-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-browser-window-created-event", GetHashCode());
                 }
                 _browserWindowCreated += value;
             }
             remove
             {
                 _browserWindowCreated -= value;
-
-                if (_browserWindowCreated == null)
-                    BridgeConnector.Socket.Off("app-browser-window-created" + GetHashCode());
             }
         }
 
+        public void TriggerOnBrowserWindowCreated()
+        {
+            _browserWindowCreated();
+        }
+
         private event Action _browserWindowCreated;
 
         /// 
@@ -307,24 +343,21 @@ public event Action WebContentsCreated
             {
                 if (_webContentsCreated == null)
                 {
-                    BridgeConnector.Socket.On("app-web-contents-created" + GetHashCode(), () =>
-                    {
-                        _webContentsCreated();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-web-contents-created-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-web-contents-created-event", GetHashCode());
                 }
                 _webContentsCreated += value;
             }
             remove
             {
                 _webContentsCreated -= value;
-
-                if (_webContentsCreated == null)
-                    BridgeConnector.Socket.Off("app-web-contents-created" + GetHashCode());
             }
         }
 
+        public void TriggerOnWebContentsCreated()
+        {
+            _browserWindowCreated();
+        }
+
         private event Action _webContentsCreated;
 
         /// 
@@ -332,40 +365,39 @@ public event Action WebContentsCreated
         /// screen readers, are enabled or disabled. See https://www.chromium.org/developers/design-documents/accessibility for more details.
         /// 
         ///  when Chrome's accessibility support is enabled,  otherwise.
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public event Action AccessibilitySupportChanged
         {
             add
             {
                 if (_accessibilitySupportChanged == null)
                 {
-                    BridgeConnector.Socket.On("app-accessibility-support-changed" + GetHashCode(), (state) =>
-                    {
-                        _accessibilitySupportChanged((bool)state);
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-accessibility-support-changed-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-accessibility-support-changed-event", GetHashCode());
                 }
                 _accessibilitySupportChanged += value;
             }
             remove
             {
                 _accessibilitySupportChanged -= value;
-
-                if (_accessibilitySupportChanged == null)
-                    BridgeConnector.Socket.Off("app-accessibility-support-changed" + GetHashCode());
             }
         }
 
+        public void TriggerOnAccessibilitySupportChanged(bool state)
+        {
+            _accessibilitySupportChanged(state);
+        }
+
         private event Action _accessibilitySupportChanged;
 
         /// 
         /// Emitted when the application has finished basic startup.
         /// 
-        public event Action Ready 
+        public event Action Ready
         {
             add
             {
-                if(IsReady)
+                if (IsReady)
                 {
                     value();
                 }
@@ -383,14 +415,14 @@ public event Action Ready
         /// 
         /// Application host fully started.
         /// 
-        public bool IsReady 
-        { 
+        public bool IsReady
+        {
             get { return _isReady; }
             internal set
             {
                 _isReady = value;
 
-                if(value)
+                if (value)
                 {
                     _ready?.Invoke();
                 }
@@ -405,36 +437,33 @@ internal set
         /// 
         /// On Windows, you have to parse the arguments using App.CommandLine to get the filepath.
         /// 
+        [SupportedOSPlatform("macos")]
         public event Action OpenFile
         {
             add
             {
                 if (_openFile == null)
                 {
-                    BridgeConnector.Socket.On("app-open-file" + GetHashCode(), (file) =>
-                    {
-                        _openFile(file.ToString());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-open-file-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-open-file-event", GetHashCode());
                 }
                 _openFile += value;
             }
             remove
             {
                 _openFile -= value;
-
-                if (_openFile == null)
-                    BridgeConnector.Socket.Off("app-open-file" + GetHashCode());
             }
         }
 
+        public void TriggerOnOpenFile(string openFile)
+        {
+            _openFile(openFile);
+        }
+
         private event Action _openFile;
 
 
         /// 
-        /// Emitted when a MacOS user wants to open a URL with the application. Your application's Info.plist file must
-        /// define the URL scheme within the CFBundleURLTypes key, and set NSPrincipalClass to AtomApplication.
+        /// Emitted when a user wants to open a URL with the application. See https://www.electronjs.org/docs/latest/tutorial/launch-app-from-url-in-another-app for more information.
         /// 
         public event Action OpenUrl
         {
@@ -442,24 +471,22 @@ public event Action OpenUrl
             {
                 if (_openUrl == null)
                 {
-                    BridgeConnector.Socket.On("app-open-url" + GetHashCode(), (url) =>
-                    {
-                        _openUrl(url.ToString());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-app-open-url-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-app-open-url-event", GetHashCode());
                 }
                 _openUrl += value;
             }
             remove
             {
                 _openUrl -= value;
-
-                if (_openUrl == null)
-                    BridgeConnector.Socket.Off("app-open-url" + GetHashCode());
             }
         }
 
+        public void TriggerOnOpenUrl(string openUrl)
+        {
+            _openUrl(openUrl);
+        }
+
+
         private event Action _openUrl;
 
         /// 
@@ -479,7 +506,7 @@ public string Name
             }
             set
             {
-                BridgeConnector.Socket.Emit("appSetName", value);
+                Electron.SignalrElectron.Clients.All.SendAsync("appSetName", value);
             }
         }
 
@@ -499,13 +526,8 @@ public Task NameAsync
                 {
                     var taskCompletionSource = new TaskCompletionSource();
 
-                    BridgeConnector.Socket.On("appGetNameCompleted", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("appGetNameCompleted");
-                        taskCompletionSource.SetResult((string)result);
-                    });
-
-                    BridgeConnector.Socket.Emit("appGetName");
+                    var signalrResult = SignalrSerializeHelper.GetSignalrResultString("appGetName");
+                    taskCompletionSource.SetResult(signalrResult.Result);
 
                     return taskCompletionSource.Task;
                 });
@@ -513,8 +535,12 @@ public Task NameAsync
         }
 
 
-        internal App() 
+        private App()
         {
+            if (OperatingSystem.IsMacOS() || OperatingSystem.IsLinux())
+            {
+                AppContext.SetSwitch("System.Drawing.EnableUnixSupport", true);
+            }
             CommandLine = new CommandLine();
         }
 
@@ -526,7 +552,7 @@ internal static App Instance
                 {
                     lock (_syncRoot)
                     {
-                        if(_app == null)
+                        if (_app == null)
                         {
                             _app = new App();
                         }
@@ -537,8 +563,16 @@ internal static App Instance
             }
         }
 
+        /// 
+        /// Manually set that the app is ready instead of using the UseElectron extension method
+        /// 
+        public static void ManuallySetIsReady()
+        {
+            Instance.IsReady = true;
+        }
+
         private static App _app;
-        private static object _syncRoot = new object();
+        private static readonly object _syncRoot = new object();
 
         private readonly JsonSerializer _jsonSerializer = new JsonSerializer()
         {
@@ -551,9 +585,9 @@ internal static App Instance
         /// guarantees that all beforeunload and unload event handlers are correctly executed. It is possible
         /// that a window cancels the quitting by returning  in the beforeunload event handler.
         /// 
-        public void Quit()
+        public async void Quit()
         {
-            BridgeConnector.Socket.Emit("appQuit");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appQuit");
         }
 
         /// 
@@ -561,9 +595,9 @@ public void Quit()
         /// events will not be emitted.
         /// 
         /// Exits immediately with exitCode. exitCode defaults to 0.
-        public void Exit(int exitCode = 0)
+        public async void Exit(int exitCode = 0)
         {
-            BridgeConnector.Socket.Emit("appExit", exitCode);
+            await Electron.SignalrElectron.Clients.All.SendAsync("appExit", exitCode);
         }
 
         /// 
@@ -576,9 +610,9 @@ public void Exit(int exitCode = 0)
         /// When  is called for multiple times, multiple instances will be started after current instance
         /// exited.
         /// 
-        public void Relaunch()
+        public async void Relaunch()
         {
-            BridgeConnector.Socket.Emit("appRelaunch");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appRelaunch");
         }
 
         /// 
@@ -594,18 +628,18 @@ public void Relaunch()
         /// exited.
         /// 
         /// Options for the relaunch.
-        public void Relaunch(RelaunchOptions relaunchOptions)
+        public async void Relaunch(RelaunchOptions relaunchOptions)
         {
-            BridgeConnector.Socket.Emit("appRelaunch", JObject.FromObject(relaunchOptions, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("appRelaunch", JObject.FromObject(relaunchOptions, _jsonSerializer));
         }
 
         /// 
         /// On Linux, focuses on the first visible window. On macOS, makes the application the active app. On Windows, focuses
         /// on the application's first window.
         /// 
-        public void Focus()
+        public async void Focus()
         {
-            BridgeConnector.Socket.Emit("appFocus");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appFocus");
         }
 
         /// 
@@ -614,25 +648,28 @@ public void Focus()
         /// 
         /// You should seek to use the  option as sparingly as possible.
         /// 
-        public void Focus(FocusOptions focusOptions)
+        [SupportedOSPlatform("macos")]
+        public async void Focus(FocusOptions focusOptions)
         {
-            BridgeConnector.Socket.Emit("appFocus", JObject.FromObject(focusOptions, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("appFocus", JObject.FromObject(focusOptions, _jsonSerializer));
         }
 
         /// 
         /// Hides all application windows without minimizing them.
         /// 
-        public void Hide()
+        [SupportedOSPlatform("macos")]
+        public async void Hide()
         {
-            BridgeConnector.Socket.Emit("appHide");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appHide");
         }
 
         /// 
         /// Shows application windows after they were hidden. Does not automatically focus them.
         /// 
-        public void Show()
+        [SupportedOSPlatform("macos")]
+        public async void Show()
         {
-            BridgeConnector.Socket.Emit("appShow");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appShow");
         }
 
         /// 
@@ -640,22 +677,7 @@ public void Show()
         /// 
         public async Task GetAppPathAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using(cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetAppPathCompleted", (path) =>
-                {
-                    BridgeConnector.Socket.Off("appGetAppPathCompleted");
-                    taskCompletionSource.SetResult(path.ToString());
-                });
-
-                BridgeConnector.Socket.Emit("appGetAppPath");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }            
+            return (await SignalrSerializeHelper.GetSignalrResultString("appGetAppPath"));
         }
 
         /// 
@@ -666,9 +688,9 @@ public async Task GetAppPathAsync(CancellationToken cancellationToken =
         /// ~/Library/Logs/YourAppName on macOS, and inside the userData directory on Linux and Windows.
         /// 
         /// A custom path for your logs. Must be absolute.
-        public void SetAppLogsPath(string path)
+        public async void SetAppLogsPath(string path)
         {
-            BridgeConnector.Socket.Emit("appSetAppLogsPath", path);
+            await Electron.SignalrElectron.Clients.All.SendAsync("appSetAppLogsPath", path);
         }
 
         /// 
@@ -681,23 +703,7 @@ public void SetAppLogsPath(string path)
         /// A path to a special directory or file associated with name.
         public async Task GetPathAsync(PathName pathName, CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using(cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetPathCompleted", (path) =>
-                {
-                    BridgeConnector.Socket.Off("appGetPathCompleted");
-
-                    taskCompletionSource.SetResult(path.ToString());
-                });
-
-                BridgeConnector.Socket.Emit("appGetPath", pathName.GetDescription());
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }  
+            return (await SignalrSerializeHelper.GetSignalrResultString("appGetPath", pathName.GetDescription()));
         }
 
         /// 
@@ -712,9 +718,9 @@ public async Task GetPathAsync(PathName pathName, CancellationToken canc
         /// Special directory.
         /// New path to a special directory.
         /// 
-        public void SetPath(PathName name, string path)
+        public async void SetPath(PathName name, string path)
         {
-            BridgeConnector.Socket.Emit("appSetPath", name.GetDescription(), path);
+            await Electron.SignalrElectron.Clients.All.SendAsync("appSetPath", name.GetDescription(), path);
         }
 
         /// 
@@ -724,22 +730,7 @@ public void SetPath(PathName name, string path)
         /// The version of the loaded application.
         public async Task GetVersionAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using(cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetVersionCompleted", (version) =>
-                {
-                    BridgeConnector.Socket.Off("appGetVersionCompleted");
-                    taskCompletionSource.SetResult(version.ToString());
-                });
-
-                BridgeConnector.Socket.Emit("appGetVersion");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return (await SignalrSerializeHelper.GetSignalrResultString("appGetVersion"));
         }
 
         /// 
@@ -752,22 +743,7 @@ public async Task GetVersionAsync(CancellationToken cancellationToken =
         /// The current application locale.
         public async Task GetLocaleAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetLocaleCompleted", (local) =>
-                {
-                    BridgeConnector.Socket.Off("appGetLocaleCompleted");
-                    taskCompletionSource.SetResult(local.ToString());
-                });
-
-                BridgeConnector.Socket.Emit("appGetLocale");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return (await SignalrSerializeHelper.GetSignalrResultString("appGetLocale"));
         }
 
         /// 
@@ -775,17 +751,21 @@ public async Task GetLocaleAsync(CancellationToken cancellationToken = d
         /// list from the task bar, and on macOS you can visit it from dock menu.
         /// 
         /// Path to add.
-        public void AddRecentDocument(string path)
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
+        public async void AddRecentDocument(string path)
         {
-            BridgeConnector.Socket.Emit("appAddRecentDocument", path);
+            await Electron.SignalrElectron.Clients.All.SendAsync("appAddRecentDocument", path);
         }
 
         /// 
         /// Clears the recent documents list.
         /// 
-        public void ClearRecentDocuments()
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
+        public async void ClearRecentDocuments()
         {
-            BridgeConnector.Socket.Emit("appClearRecentDocuments");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appClearRecentDocuments");
         }
 
         /// 
@@ -813,6 +793,8 @@ public void ClearRecentDocuments()
         /// call this method with electron as the parameter.
         /// The cancellation token.
         /// Whether the call succeeded.
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task SetAsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default)
         {
             return await SetAsDefaultProtocolClientAsync(protocol, null, null, cancellationToken);
@@ -844,6 +826,8 @@ public async Task SetAsDefaultProtocolClientAsync(string protocol, Cancell
         /// The path to the Electron executable. Defaults to process.execPath
         /// The cancellation token.
         /// Whether the call succeeded.
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task SetAsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default)
         {
             return await SetAsDefaultProtocolClientAsync(protocol, path, null, cancellationToken);
@@ -876,24 +860,11 @@ public async Task SetAsDefaultProtocolClientAsync(string protocol, string
         /// Arguments passed to the executable. Defaults to an empty array.
         /// The cancellation token.
         /// Whether the call succeeded.
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task SetAsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appSetAsDefaultProtocolClientCompleted", (success) =>
-                {
-                    BridgeConnector.Socket.Off("appSetAsDefaultProtocolClientCompleted");
-                    taskCompletionSource.SetResult((bool) success);
-                });
-
-                BridgeConnector.Socket.Emit("appSetAsDefaultProtocolClient", protocol, path, args);
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultBool("appSetAsDefaultProtocolClient", protocol, path, args);
         }
 
         /// 
@@ -903,6 +874,8 @@ public async Task SetAsDefaultProtocolClientAsync(string protocol, string
         /// The name of your protocol, without ://.
         /// The cancellation token.
         /// Whether the call succeeded.
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task RemoveAsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default)
         {
             return await RemoveAsDefaultProtocolClientAsync(protocol, null, null, cancellationToken);
@@ -916,6 +889,8 @@ public async Task RemoveAsDefaultProtocolClientAsync(string protocol, Canc
         /// Defaults to process.execPath.
         /// The cancellation token.
         /// Whether the call succeeded.
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task RemoveAsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default)
         {
             return await RemoveAsDefaultProtocolClientAsync(protocol, path, null, cancellationToken);
@@ -930,24 +905,11 @@ public async Task RemoveAsDefaultProtocolClientAsync(string protocol, stri
         /// Defaults to an empty array.
         /// The cancellation token.
         /// Whether the call succeeded.
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task RemoveAsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default)
-        {           
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appRemoveAsDefaultProtocolClientCompleted", (success) =>
-                {
-                    BridgeConnector.Socket.Off("appRemoveAsDefaultProtocolClientCompleted");
-                    taskCompletionSource.SetResult((bool) success);
-                });
-
-                BridgeConnector.Socket.Emit("appRemoveAsDefaultProtocolClient", protocol, path, args);
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+        {
+            return await SignalrSerializeHelper.GetSignalrResultBool("appRemoveAsDefaultProtocolClient", protocol, path, args);
         }
 
         /// 
@@ -963,6 +925,8 @@ public async Task RemoveAsDefaultProtocolClientAsync(string protocol, stri
         /// The name of your protocol, without ://.
         /// The cancellation token.
         /// Whether the current executable is the default handler for a protocol (aka URI scheme).
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task IsDefaultProtocolClientAsync(string protocol, CancellationToken cancellationToken = default)
         {
             return await IsDefaultProtocolClientAsync(protocol, null, null, cancellationToken);
@@ -982,6 +946,8 @@ public async Task IsDefaultProtocolClientAsync(string protocol, Cancellati
         /// Defaults to process.execPath.
         /// The cancellation token.
         /// Whether the current executable is the default handler for a protocol (aka URI scheme).
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task IsDefaultProtocolClientAsync(string protocol, string path, CancellationToken cancellationToken = default)
         {
             return await IsDefaultProtocolClientAsync(protocol, path, null, cancellationToken);
@@ -1002,24 +968,11 @@ public async Task IsDefaultProtocolClientAsync(string protocol, string pat
         /// Defaults to an empty array.
         /// The cancellation token.
         /// Whether the current executable is the default handler for a protocol (aka URI scheme).
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public async Task IsDefaultProtocolClientAsync(string protocol, string path, string[] args, CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appIsDefaultProtocolClientCompleted", (success) =>
-                {
-                    BridgeConnector.Socket.Off("appIsDefaultProtocolClientCompleted");
-                    taskCompletionSource.SetResult((bool) success);
-                });
-
-                BridgeConnector.Socket.Emit("appIsDefaultProtocolClient", protocol, path, args);
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultBool("appIsDefaultProtocolClient", protocol, path, args);
         }
 
         /// 
@@ -1030,24 +983,10 @@ public async Task IsDefaultProtocolClientAsync(string protocol, string pat
         /// Array of  objects.
         /// The cancellation token.
         /// Whether the call succeeded.
+        [SupportedOSPlatform("windows")]
         public async Task SetUserTasksAsync(UserTask[] userTasks, CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appSetUserTasksCompleted", (success) =>
-                {
-                    BridgeConnector.Socket.Off("appSetUserTasksCompleted");
-                    taskCompletionSource.SetResult((bool) success);
-                });
-
-                BridgeConnector.Socket.Emit("appSetUserTasks", JArray.FromObject(userTasks, _jsonSerializer));
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultBool("appSetUserTasks", JArray.FromObject(userTasks, _jsonSerializer));
         }
 
         /// 
@@ -1055,24 +994,11 @@ public async Task SetUserTasksAsync(UserTask[] userTasks, CancellationToke
         /// 
         /// The cancellation token.
         /// Jump List settings.
+        [SupportedOSPlatform("windows")]
         public async Task GetJumpListSettingsAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetJumpListSettingsCompleted", (jumpListSettings) =>
-                {
-                    BridgeConnector.Socket.Off("appGetJumpListSettingsCompleted");
-                    taskCompletionSource.SetResult(JObject.Parse(jumpListSettings.ToString()).ToObject());
-                });
-
-                BridgeConnector.Socket.Emit("appGetJumpListSettings");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultJObject("appGetJumpListSettings");
+            return signalrResult.ToObject();
         }
 
         /// 
@@ -1091,11 +1017,13 @@ public async Task GetJumpListSettingsAsync(CancellationToken c
         /// omitted from the Jump List. The list of removed items can be obtained using .
         /// 
         /// Array of  objects.
-        public void SetJumpList(JumpListCategory[] categories)
+        [SupportedOSPlatform("windows")]
+        public async void SetJumpList(JumpListCategory[] categories)
         {
-            BridgeConnector.Socket.Emit("appSetJumpList", JArray.FromObject(categories, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("appSetJumpList", JArray.FromObject(categories, _jsonSerializer));
         }
 
+        // ToDo: Need better option
         /// 
         /// The return value of this method indicates whether or not this instance of your application successfully obtained
         /// the lock. If it failed to obtain the lock, you can assume that another instance of your application is already
@@ -1119,41 +1047,29 @@ public void SetJumpList(JumpListCategory[] categories)
         /// 
         public async Task RequestSingleInstanceLockAsync(Action newInstanceOpened, CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
+            // ToDo: Check this function - Unsure if it's working as expected
+            // Check if second-instance is getting triggereds
+            var secondInstanceListener = await SignalrSerializeHelper.GetSignalrResultJArray("appRequestSingleInstanceLock");
+            if (secondInstanceListener != null)
             {
-                BridgeConnector.Socket.On("appRequestSingleInstanceLockCompleted", (success) =>
-                {
-                    BridgeConnector.Socket.Off("appRequestSingleInstanceLockCompleted");
-                    taskCompletionSource.SetResult((bool)success);
-                });
-
-                BridgeConnector.Socket.Off("secondInstance");
-                BridgeConnector.Socket.On("secondInstance", (result) =>
-                {
-                    JArray results = (JArray)result;
-                    string[] args = results.First.ToObject();
-                    string workingDirectory = results.Last.ToObject();
-
-                    newInstanceOpened(args, workingDirectory);
-                });
-
-                BridgeConnector.Socket.Emit("appRequestSingleInstanceLock");
+                JArray results = secondInstanceListener;
+                string[] args = results.First.ToObject();
+                string workingDirectory = results.Last.ToObject();
 
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
+                newInstanceOpened(args, workingDirectory);
             }
+
+            return (await SignalrSerializeHelper.GetSignalrResultBool("appRequestSingleInstanceLock"));
         }
 
+
         /// 
         /// Releases all locks that were created by makeSingleInstance. This will allow
         /// multiple instances of the application to once again run side by side.
         /// 
-        public void ReleaseSingleInstanceLock()
+        public async void ReleaseSingleInstanceLock()
         {
-            BridgeConnector.Socket.Emit("appReleaseSingleInstanceLock");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appReleaseSingleInstanceLock");
         }
 
         /// 
@@ -1164,22 +1080,7 @@ public void ReleaseSingleInstanceLock()
         /// The cancellation token.
         public async Task HasSingleInstanceLockAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appHasSingleInstanceLockCompleted", (hasLock) =>
-                {
-                    BridgeConnector.Socket.Off("appHasSingleInstanceLockCompleted");
-                    taskCompletionSource.SetResult((bool) hasLock);
-                });
-
-                BridgeConnector.Socket.Emit("appHasSingleInstanceLock");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultBool("appHasSingleInstanceLock");
         }
 
         /// 
@@ -1189,6 +1090,7 @@ public async Task HasSingleInstanceLockAsync(CancellationToken cancellatio
         /// 
         /// Uniquely identifies the activity. Maps to NSUserActivity.activityType.
         /// App-specific state to store for use by another device.
+        [SupportedOSPlatform("macos")]
         public void SetUserActivity(string type, object userInfo)
         {
             SetUserActivity(type, userInfo, null);
@@ -1206,58 +1108,48 @@ public void SetUserActivity(string type, object userInfo)
         /// 
         /// The webpage to load in a browser if no suitable app is installed on the resuming device. The scheme must be http or https.
         /// 
-        public void SetUserActivity(string type, object userInfo, string webpageUrl)
+        [SupportedOSPlatform("macos")]
+        public async void SetUserActivity(string type, object userInfo, string webpageUrl)
         {
-            BridgeConnector.Socket.Emit("appSetUserActivity", type, userInfo, webpageUrl);
+            await Electron.SignalrElectron.Clients.All.SendAsync("appSetUserActivity", type, userInfo, webpageUrl);
         }
 
         /// 
         /// The type of the currently running activity.
         /// 
         /// The cancellation token.
+        [SupportedOSPlatform("macos")]
         public async Task GetCurrentActivityTypeAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetCurrentActivityTypeCompleted", (activityType) =>
-                {
-                    BridgeConnector.Socket.Off("appGetCurrentActivityTypeCompleted");
-                    taskCompletionSource.SetResult(activityType.ToString());
-                });
-
-                BridgeConnector.Socket.Emit("appGetCurrentActivityType");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultString("appGetCurrentActivityType");
         }
 
         /// 
         /// Invalidates the current Handoff user activity.
         /// 
-        public void InvalidateCurrentActivity()
+        [SupportedOSPlatform("macos")]
+        public async void InvalidateCurrentActivity()
         {
-            BridgeConnector.Socket.Emit("appInvalidateCurrentActivity");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appInvalidateCurrentActivity");
         }
 
         /// 
         /// Marks the current Handoff user activity as inactive without invalidating it.
         /// 
-        public void ResignCurrentActivity()
+        [SupportedOSPlatform("macos")]
+        public async void ResignCurrentActivity()
         {
-            BridgeConnector.Socket.Emit("appResignCurrentActivity");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appResignCurrentActivity");
         }
 
         /// 
         /// Changes the Application User Model ID to id.
         /// 
         /// Model Id.
-        public void SetAppUserModelId(string id)
+        [SupportedOSPlatform("windows")]
+        public async void SetAppUserModelId(string id)
         {
-            BridgeConnector.Socket.Emit("appSetAppUserModelId", id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("appSetAppUserModelId", id);
         }
 
         /// TODO: Check new parameter which is a function [App.ImportCertificate]
@@ -1269,24 +1161,10 @@ public void SetAppUserModelId(string id)
         /// 
         /// The cancellation token.
         /// Result of import. Value of 0 indicates success.
+        [SupportedOSPlatform("linux")]
         public async Task ImportCertificateAsync(ImportCertificateOptions options, CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appImportCertificateCompleted", (result) =>
-                {
-                    BridgeConnector.Socket.Off("appImportCertificateCompleted");
-                    taskCompletionSource.SetResult((int) result);
-                });
-
-                BridgeConnector.Socket.Emit("appImportCertificate", JObject.FromObject(options, _jsonSerializer));
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultInt("appImportCertificate", JObject.FromObject(options, _jsonSerializer));
         }
 
         /// 
@@ -1299,24 +1177,8 @@ public async Task ImportCertificateAsync(ImportCertificateOptions options,
         /// 
         public async Task GetAppMetricsAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetAppMetricsCompleted", (result) =>
-                {
-                    BridgeConnector.Socket.Off("appGetAppMetricsCompleted");
-                    var processMetrics = ((JArray)result).ToObject();
-
-                    taskCompletionSource.SetResult(processMetrics);
-                });
-
-                BridgeConnector.Socket.Emit("appGetAppMetrics");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultJArray("appGetAppMetrics");
+            return signalrResult.ToObject();
         }
 
         /// 
@@ -1327,24 +1189,8 @@ public async Task GetAppMetricsAsync(CancellationToken cancella
         /// 
         public async Task GetGpuFeatureStatusAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetGpuFeatureStatusCompleted", (result) =>
-                {
-                    BridgeConnector.Socket.Off("appGetGpuFeatureStatusCompleted");
-                    var gpuFeatureStatus = ((JObject)result).ToObject();
-
-                    taskCompletionSource.SetResult(gpuFeatureStatus);
-                });
-
-                BridgeConnector.Socket.Emit("appGetGpuFeatureStatus");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultJObject("appGetGpuFeatureStatus");
+            return signalrResult.ToObject();
         }
 
         /// 
@@ -1357,48 +1203,22 @@ public async Task GetGpuFeatureStatusAsync(CancellationToken c
         /// Counter badge.
         /// The cancellation token.
         /// Whether the call succeeded.
+        [SupportedOSPlatform("linux")]
+        [SupportedOSPlatform("macos")]
         public async Task SetBadgeCountAsync(int count, CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appSetBadgeCountCompleted", (success) =>
-                {
-                    BridgeConnector.Socket.Off("appSetBadgeCountCompleted");
-                    taskCompletionSource.SetResult((bool) success);
-                });
-
-                BridgeConnector.Socket.Emit("appSetBadgeCount", count);
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultBool("appSetBadgeCount", count);
         }
 
         /// 
         /// The current value displayed in the counter badge.
         /// 
         /// The cancellation token.
+        [SupportedOSPlatform("linux")]
+        [SupportedOSPlatform("macos")]
         public async Task GetBadgeCountAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appGetBadgeCountCompleted", (count) =>
-                {
-                    BridgeConnector.Socket.Off("appGetBadgeCountCompleted");
-                    taskCompletionSource.SetResult((int)count);
-                });
-
-                BridgeConnector.Socket.Emit("appGetBadgeCount");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultInt("appGetBadgeCount");
         }
 
         /// 
@@ -1410,30 +1230,18 @@ public async Task GetBadgeCountAsync(CancellationToken cancellationToken =
         /// Whether the current desktop environment is Unity launcher.
         /// 
         /// The cancellation token.
+        [SupportedOSPlatform("linux")]
         public async Task IsUnityRunningAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appIsUnityRunningCompleted", (isUnityRunning) =>
-                {
-                    BridgeConnector.Socket.Off("appIsUnityRunningCompleted");
-                    taskCompletionSource.SetResult((bool)isUnityRunning);
-                });
-
-                BridgeConnector.Socket.Emit("appIsUnityRunning");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultBool("appIsUnityRunning");
         }
 
         /// 
         /// If you provided path and args options to  then you need to pass the same
         /// arguments here for  to be set correctly.
         /// 
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
         public async Task GetLoginItemSettingsAsync(CancellationToken cancellationToken = default)
         {
             return await GetLoginItemSettingsAsync(null, cancellationToken);
@@ -1445,34 +1253,21 @@ public async Task GetLoginItemSettingsAsync(CancellationToken
         /// 
         /// 
         /// The cancellation token.
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
         public async Task GetLoginItemSettingsAsync(LoginItemSettingsOptions options, CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
+            JObject appGetLoginItemSettingsCompleted;
+            if (options == null)
             {
-                BridgeConnector.Socket.On("appGetLoginItemSettingsCompleted", (loginItemSettings) =>
-                {
-                    BridgeConnector.Socket.Off("appGetLoginItemSettingsCompleted");
-
-                    var result = ((JObject) loginItemSettings).ToObject();
-
-                    taskCompletionSource.SetResult(result);
-                });
-
-                if (options == null)
-                {
-                    BridgeConnector.Socket.Emit("appGetLoginItemSettings");
-                }
-                else
-                {
-                    BridgeConnector.Socket.Emit("appGetLoginItemSettings", JObject.FromObject(options, _jsonSerializer));
-                }
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
+                appGetLoginItemSettingsCompleted = await SignalrSerializeHelper.GetSignalrResultJObject("appGetLoginItemSettings");
+            }
+            else
+            {
+                appGetLoginItemSettingsCompleted = await SignalrSerializeHelper.GetSignalrResultJObject("appGetLoginItemSettingsWithOptions", JObject.FromObject(options, _jsonSerializer));
             }
+
+            return appGetLoginItemSettingsCompleted.ToObject();
         }
 
         /// 
@@ -1481,9 +1276,11 @@ public async Task GetLoginItemSettingsAsync(LoginItemSettings
         /// you'll want to set the launch path to Update.exe, and pass arguments that specify your application name.
         /// 
         /// 
-        public void SetLoginItemSettings(LoginSettings loginSettings)
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async void SetLoginItemSettings(LoginSettings loginSettings)
         {
-            BridgeConnector.Socket.Emit("appSetLoginItemSettings", JObject.FromObject(loginSettings, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("appSetLoginItemSettings", JObject.FromObject(loginSettings, _jsonSerializer));
         }
 
         /// 
@@ -1492,24 +1289,11 @@ public void SetLoginItemSettings(LoginSettings loginSettings)
         /// See Chromium's accessibility docs for more details.
         /// 
         ///  if Chrome’s accessibility support is enabled,  otherwise.
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
         public async Task IsAccessibilitySupportEnabledAsync(CancellationToken cancellationToken = default)
         {
-            cancellationToken.ThrowIfCancellationRequested();
-
-            var taskCompletionSource = new TaskCompletionSource();
-            using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
-            {
-                BridgeConnector.Socket.On("appIsAccessibilitySupportEnabledCompleted", (isAccessibilitySupportEnabled) =>
-                {
-                    BridgeConnector.Socket.Off("appIsAccessibilitySupportEnabledCompleted");
-                    taskCompletionSource.SetResult((bool)isAccessibilitySupportEnabled);
-                });
-
-                BridgeConnector.Socket.Emit("appIsAccessibilitySupportEnabled");
-
-                return await taskCompletionSource.Task
-                    .ConfigureAwait(false);
-            }
+            return await SignalrSerializeHelper.GetSignalrResultBool("appIsAccessibilitySupportEnabled");
         }
 
         /// 
@@ -1522,18 +1306,40 @@ public async Task IsAccessibilitySupportEnabledAsync(CancellationToken can
         /// Note: Rendering accessibility tree can significantly affect the performance of your app. It should not be enabled by default.
         /// 
         /// Enable or disable accessibility tree rendering.
-        public void SetAccessibilitySupportEnabled(bool enabled)
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async void SetAccessibilitySupportEnabled(bool enabled)
         {
-            BridgeConnector.Socket.Emit("appSetAboutPanelOptions", enabled);
+            await Electron.SignalrElectron.Clients.All.SendAsync("appSetAboutPanelOptions", enabled);
+        }
+
+        /// 
+        /// Fetches a path's associated icon.
+        /// 
+        /// 
+        /// 
+        public async Task GetFileIcon(string path)
+        {
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultJArray("appGetFileIcon");
+            return signalrResult[1].ToObject();
+        }
+
+        /// 
+        /// If you're using a splashscreen in the electron.manifest.json, the window will ony be fully destroyed once you call this method once.
+        /// You should only do this after creating another window, to avoid a bug where the Electron renderer process frezees till any window interaction.
+        /// 
+        public async void DestroySplashScreen()
+        {
+            await Electron.SignalrElectron.Clients.All.SendAsync("splashscreen-destroy");
         }
 
         /// 
         /// Show the app's about panel options. These options can be overridden with
         /// .
         /// 
-        public void ShowAboutPanel()
+        public async void ShowAboutPanel()
         {
-            BridgeConnector.Socket.Emit("appShowAboutPanel");
+            await Electron.SignalrElectron.Clients.All.SendAsync("appShowAboutPanel");
         }
 
         /// 
@@ -1547,9 +1353,9 @@ public void ShowAboutPanel()
         /// documentation for more information.
         /// 
         /// About panel options.
-        public void SetAboutPanelOptions(AboutPanelOptions options)
+        public async void SetAboutPanelOptions(AboutPanelOptions options)
         {
-            BridgeConnector.Socket.Emit("appSetAboutPanelOptions", JObject.FromObject(options, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("appSetAboutPanelOptions", JObject.FromObject(options, _jsonSerializer));
         }
 
         /// 
@@ -1569,7 +1375,7 @@ public string UserAgentFallback
             }
             set
             {
-                BridgeConnector.Socket.Emit("appSetUserAgentFallback", value);
+                Electron.SignalrElectron.Clients.All.SendAsync("appSetUserAgentFallback", value);
             }
         }
 
@@ -1589,13 +1395,8 @@ public Task UserAgentFallbackAsync
                 {
                     var taskCompletionSource = new TaskCompletionSource();
 
-                    BridgeConnector.Socket.On("appGetUserAgentFallbackCompleted", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("appGetUserAgentFallbackCompleted");
-                        taskCompletionSource.SetResult((string)result);
-                    });
-
-                    BridgeConnector.Socket.Emit("appGetUserAgentFallback");
+                    var signalrResult = SignalrSerializeHelper.GetSignalrResultString("appGetUserAgentFallback");
+                    taskCompletionSource.SetResult(signalrResult.Result);
 
                     return taskCompletionSource.Task;
                 });
diff --git a/ElectronNET.API/AutoUpdater.cs b/ElectronNET.API/AutoUpdater.cs
index da1001fa..0db2fcf8 100644
--- a/ElectronNET.API/AutoUpdater.cs
+++ b/ElectronNET.API/AutoUpdater.cs
@@ -1,4 +1,5 @@
 using ElectronNET.API.Entities;
+using Microsoft.AspNetCore.SignalR;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using Newtonsoft.Json.Serialization;
@@ -16,28 +17,55 @@ public sealed class AutoUpdater
         /// 
         /// Whether to automatically download an update when it is found. (Default is true)
         /// 
-        public bool AutoDownload
+        public async Task IsAutoDownloadEnabledAsync()
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
+            return await SignalrSerializeHelper.GetSignalrResultBool("autoUpdater-autoDownload-get");
+        }
 
-                    BridgeConnector.Socket.On("autoUpdater-autoDownload-get-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-autoDownload-get-reply");
-                        taskCompletionSource.SetResult((bool)result);
-                    });
+        /// 
+        /// Whether to automatically install a downloaded update on app quit (if `QuitAndInstall` was not called before).
+        /// 
+        /// Applicable only on Windows and Linux.
+        /// 
+        public async Task IsAutoInstallOnAppQuitEnabledAsync()
+        {
+            return await SignalrSerializeHelper.GetSignalrResultBool("autoUpdater-autoInstallOnAppQuit-get");
+        }
 
-                    BridgeConnector.Socket.Emit("autoUpdater-autoDownload-get");
+        /// 
+        /// *GitHub provider only.* Whether to allow update to pre-release versions. 
+        /// Defaults to "true" if application version contains prerelease components (e.g. "0.12.1-alpha.1", here "alpha" is a prerelease component), otherwise "false".
+        /// 
+        /// If "true", downgrade will be allowed("allowDowngrade" will be set to "true").
+        /// 
+        public async Task IsAllowPrereleaseEnabledAsync()
+        {
+            return await SignalrSerializeHelper.GetSignalrResultBool("autoUpdater-allowPrerelease-get");
+        }
 
-                    return taskCompletionSource.Task;
-                }).Result;
-            }
+        /// 
+        /// *GitHub provider only.* 
+        /// Get all release notes (from current version to latest), not just the latest (Default is false).
+        /// 
+        public async Task IsFullChangeLogEnabledAsync()
+        {
+            return await SignalrSerializeHelper.GetSignalrResultBool("autoUpdater-fullChangelog-get");
+        }
+
+        public async Task IsAllowDowngradeEnabledAsync()
+        {
+            return await SignalrSerializeHelper.GetSignalrResultBool("autoUpdater-allowDowngrade-get");
+        }
+        
+
+        /// 
+        /// Whether to automatically download an update when it is found. (Default is true)
+        /// 
+        public bool AutoDownload
+        {
             set
             {
-                BridgeConnector.Socket.Emit("autoUpdater-autoDownload-set", value);
+                Electron.SignalrElectron.Clients.All.SendAsync("autoUpdater-autoDownload-set", value);
             }
         }
 
@@ -48,26 +76,9 @@ public bool AutoDownload
         /// 
         public bool AutoInstallOnAppQuit
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
-
-                    BridgeConnector.Socket.On("autoUpdater-autoInstallOnAppQuit-get-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-autoInstallOnAppQuit-get-reply");
-                        taskCompletionSource.SetResult((bool)result);
-                    });
-
-                    BridgeConnector.Socket.Emit("autoUpdater-autoInstallOnAppQuit-get");
-
-                    return taskCompletionSource.Task;
-                }).Result;
-            }
             set
             {
-                BridgeConnector.Socket.Emit("autoUpdater-autoInstallOnAppQuit-set", value);
+                Electron.SignalrElectron.Clients.All.SendAsync("autoUpdater-autoInstallOnAppQuit-set", value);
             }
         }
 
@@ -79,26 +90,9 @@ public bool AutoInstallOnAppQuit
         /// 
         public bool AllowPrerelease
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
-
-                    BridgeConnector.Socket.On("autoUpdater-allowPrerelease-get-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-allowPrerelease-get-reply");
-                        taskCompletionSource.SetResult((bool)result);
-                    });
-
-                    BridgeConnector.Socket.Emit("autoUpdater-allowPrerelease-get");
-
-                    return taskCompletionSource.Task;
-                }).Result;
-            }
             set
             {
-                BridgeConnector.Socket.Emit("autoUpdater-allowPrerelease-set", value);
+                Electron.SignalrElectron.Clients.All.SendAsync("autoUpdater-allowPrerelease-set", value);
             }
         }
 
@@ -108,26 +102,9 @@ public bool AllowPrerelease
         /// 
         public bool FullChangelog
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
-
-                    BridgeConnector.Socket.On("autoUpdater-fullChangelog-get-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-fullChangelog-get-reply");
-                        taskCompletionSource.SetResult((bool)result);
-                    });
-
-                    BridgeConnector.Socket.Emit("autoUpdater-fullChangelog-get");
-
-                    return taskCompletionSource.Task;
-                }).Result;
-            }
             set
             {
-                BridgeConnector.Socket.Emit("autoUpdater-fullChangelog-set", value);
+                Electron.SignalrElectron.Clients.All.SendAsync("autoUpdater-fullChangelog-set", value);
             }
         }
 
@@ -138,136 +115,48 @@ public bool FullChangelog
         /// 
         public bool AllowDowngrade
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
-
-                    BridgeConnector.Socket.On("autoUpdater-allowDowngrade-get-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-allowDowngrade-get-reply");
-                        taskCompletionSource.SetResult((bool)result);
-                    });
-
-                    BridgeConnector.Socket.Emit("autoUpdater-allowDowngrade-get");
-
-                    return taskCompletionSource.Task;
-                }).Result;
-            }
             set
             {
-                BridgeConnector.Socket.Emit("autoUpdater-allowDowngrade-set", value);
+                Electron.SignalrElectron.Clients.All.SendAsync("autoUpdater-allowDowngrade-set", value);
             }
         }
 
         /// 
         /// For test only.
         /// 
-        public string UpdateConfigPath
+        public async Task GetUpdateConfigPathAsync()
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
-
-                    BridgeConnector.Socket.On("autoUpdater-updateConfigPath-get-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-updateConfigPath-get-reply");
-                        taskCompletionSource.SetResult(result.ToString());
-                    });
-
-                    BridgeConnector.Socket.Emit("autoUpdater-updateConfigPath-get");
-
-                    return taskCompletionSource.Task;
-                }).Result;
-            }
+            return await SignalrSerializeHelper.GetSignalrResultString("autoUpdater-updateConfigPath-get");
         }
-
+        
         /// 
         /// The current application version
         /// 
-        public Task CurrentVersionAsync
+        public async Task GetCurrentVersionAsync()
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
-
-                    BridgeConnector.Socket.On("autoUpdater-currentVersion-get-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-currentVersion-get-reply");
-                        SemVer version = ((JObject)result).ToObject();
-                        taskCompletionSource.SetResult(version);
-                    });
-                    BridgeConnector.Socket.Emit("autoUpdater-currentVersion-get");
-
-                    return taskCompletionSource.Task;
-                });
-            }
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultString("autoUpdater-updateConcurrentVersionfigPath-get");
+            SemVer version = ((JObject)signalrResult).ToObject();
+            return version;
         }
 
-        /// 
-        /// Get the update channel. Not applicable for GitHub. 
-        /// Doesn’t return channel from the update configuration, only if was previously set.
-        /// 
-        [Obsolete("Use the asynchronous version ChannelAsync instead")]
-        public string Channel
-        {
-            get
-            {
-                return ChannelAsync.Result;
-            }
-        }
 
         /// 
         /// Get the update channel. Not applicable for GitHub. 
         /// Doesn’t return channel from the update configuration, only if was previously set.
         /// 
-        public Task ChannelAsync
+        public async Task GetChannelAsync()
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
-
-                    BridgeConnector.Socket.On("autoUpdater-channel-get-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-channel-get-reply");
-                        taskCompletionSource.SetResult(result.ToString());
-                    });
-                    BridgeConnector.Socket.Emit("autoUpdater-channel-get");
-
-                    return taskCompletionSource.Task;
-                });
-            }
+            return await SignalrSerializeHelper.GetSignalrResultString("autoUpdater-channel-get");
         }
 
-
-
         /// 
         /// The request headers.
         /// 
-        public Task> RequestHeadersAsync
+        public async Task> GetRequestHeadersAsync()
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource>();
-                    BridgeConnector.Socket.On("autoUpdater-requestHeaders-get-reply", (headers) =>
-                    {
-                        BridgeConnector.Socket.Off("autoUpdater-requestHeaders-get-reply");
-                        Dictionary result = ((JObject)headers).ToObject>();
-                        taskCompletionSource.SetResult(result);
-                    });
-                    BridgeConnector.Socket.Emit("autoUpdater-requestHeaders-get");
-                    return taskCompletionSource.Task;
-                });
-            }
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultJObject("autoUpdater-requestHeaders-get");
+            Dictionary result = signalrResult.ToObject>();
+            return result;
         }
 
         /// 
@@ -277,7 +166,7 @@ public Dictionary RequestHeaders
         {
             set
             {
-                BridgeConnector.Socket.Emit("autoUpdater-requestHeaders-set", JObject.FromObject(value, _jsonSerializer));
+                Electron.SignalrElectron.Clients.All.SendAsync("autoUpdater-requestHeaders-set", JObject.FromObject(value, _jsonSerializer));
             }
         }
 
@@ -290,24 +179,22 @@ public event Action OnError
             {
                 if (_error == null)
                 {
-                    BridgeConnector.Socket.On("autoUpdater-error" + GetHashCode(), (message) =>
-                    {
-                        _error(message.ToString());
-                    });
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-autoUpdater-error-event", GetHashCode());
 
-                    BridgeConnector.Socket.Emit("register-autoUpdater-error-event", GetHashCode());
                 }
                 _error += value;
             }
             remove
             {
                 _error -= value;
-
-                if (_error == null)
-                    BridgeConnector.Socket.Off("autoUpdater-error" + GetHashCode());
             }
         }
 
+        public void TriggerOnError(string error)
+        {
+            _error(error);
+        }
+
         private event Action _error;
 
         /// 
@@ -319,24 +206,22 @@ public event Action OnCheckingForUpdate
             {
                 if (_checkingForUpdate == null)
                 {
-                    BridgeConnector.Socket.On("autoUpdater-checking-for-update" + GetHashCode(), () =>
-                    {
-                        _checkingForUpdate();
-                    });
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-autoUpdater-checking-for-update-event", GetHashCode());
 
-                    BridgeConnector.Socket.Emit("register-autoUpdater-checking-for-update-event", GetHashCode());
                 }
                 _checkingForUpdate += value;
             }
             remove
             {
                 _checkingForUpdate -= value;
-
-                if (_checkingForUpdate == null)
-                    BridgeConnector.Socket.Off("autoUpdater-checking-for-update" + GetHashCode());
             }
         }
 
+        public void TriggerOnCheckingForUpdate()
+        {
+            _checkingForUpdate();
+        }
+
         private event Action _checkingForUpdate;
 
         /// 
@@ -349,24 +234,21 @@ public event Action OnUpdateAvailable
             {
                 if (_updateAvailable == null)
                 {
-                    BridgeConnector.Socket.On("autoUpdater-update-available" + GetHashCode(), (updateInfo) =>
-                    {
-                        _updateAvailable(JObject.Parse(updateInfo.ToString()).ToObject());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-autoUpdater-update-available-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-autoUpdater-update-available-event", GetHashCode());
                 }
                 _updateAvailable += value;
             }
             remove
             {
                 _updateAvailable -= value;
-
-                if (_updateAvailable == null)
-                    BridgeConnector.Socket.Off("autoUpdater-update-available" + GetHashCode());
             }
         }
 
+        public void TriggerOnUpdateAvailable(JObject jobject)
+        {
+            _updateAvailable(JObject.Parse(jobject.ToString()).ToObject());
+        }
+
         private event Action _updateAvailable;
 
         /// 
@@ -378,24 +260,21 @@ public event Action OnUpdateNotAvailable
             {
                 if (_updateNotAvailable == null)
                 {
-                    BridgeConnector.Socket.On("autoUpdater-update-not-available" + GetHashCode(), (updateInfo) =>
-                    {
-                        _updateNotAvailable(JObject.Parse(updateInfo.ToString()).ToObject());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-autoUpdater-update-not-available-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-autoUpdater-update-not-available-event", GetHashCode());
                 }
                 _updateNotAvailable += value;
             }
             remove
             {
                 _updateNotAvailable -= value;
-
-                if (_updateNotAvailable == null)
-                    BridgeConnector.Socket.Off("autoUpdater-update-not-available" + GetHashCode());
             }
         }
 
+        public void TriggerOnUpdateNotAvailable(JObject jobject)
+        {
+            _updateNotAvailable(JObject.Parse(jobject.ToString()).ToObject());
+        }
+
         private event Action _updateNotAvailable;
 
         /// 
@@ -407,24 +286,21 @@ public event Action OnDownloadProgress
             {
                 if (_downloadProgress == null)
                 {
-                    BridgeConnector.Socket.On("autoUpdater-download-progress" + GetHashCode(), (progressInfo) =>
-                    {
-                        _downloadProgress(JObject.Parse(progressInfo.ToString()).ToObject());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-autoUpdater-download-progress-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-autoUpdater-download-progress-event", GetHashCode());
                 }
                 _downloadProgress += value;
             }
             remove
             {
                 _downloadProgress -= value;
-
-                if (_downloadProgress == null)
-                    BridgeConnector.Socket.Off("autoUpdater-download-progress" + GetHashCode());
             }
         }
 
+        public void TriggerOnDownloadProgress(JObject jobject)
+        {
+            _downloadProgress(JObject.Parse(jobject.ToString()).ToObject());
+        }
+
         private event Action _downloadProgress;
 
         /// 
@@ -436,28 +312,25 @@ public event Action OnUpdateDownloaded
             {
                 if (_updateDownloaded == null)
                 {
-                    BridgeConnector.Socket.On("autoUpdater-update-downloaded" + GetHashCode(), (updateInfo) =>
-                    {
-                        _updateDownloaded(JObject.Parse(updateInfo.ToString()).ToObject());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-autoUpdater-update-downloaded-event", GetHashCode());
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-autoUpdater-update-downloaded-event", GetHashCode());
                 }
                 _updateDownloaded += value;
             }
             remove
             {
                 _updateDownloaded -= value;
-
-                if (_updateDownloaded == null)
-                    BridgeConnector.Socket.Off("autoUpdater-update-downloaded" + GetHashCode());
             }
         }
 
+        public void TriggerOnUpdateDownloaded(JObject jobject)
+        {
+            _updateDownloaded(JObject.Parse(jobject.ToString()).ToObject());
+        }
+
         private event Action _updateDownloaded;
 
         private static AutoUpdater _autoUpdater;
-        private static object _syncRoot = new object();
+        private static readonly object _syncRoot = new();
 
         internal AutoUpdater() { }
 
@@ -484,37 +357,31 @@ internal static AutoUpdater Instance
         /// Asks the server whether there is an update.
         /// 
         /// 
-        public Task CheckForUpdatesAsync()
+        public async Task CheckForUpdatesAsync()
         {
             var taskCompletionSource = new TaskCompletionSource();
-            string guid = Guid.NewGuid().ToString();
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultJObject("autoUpdaterCheckForUpdates");
 
-            BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesComplete" + guid, (updateCheckResult) =>
+            if (signalrResult["errno"] != null)
+            {
+                string message = "An error occurred in CheckForUpdatesAsync";
+                message = JsonConvert.SerializeObject(signalrResult);
+                taskCompletionSource.SetException(new Exception(message));
+            } 
+            else
             {
                 try
                 {
-                    BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid);
-                    BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesError" + guid);
-                    taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject());
+                    var updateCheckResult = signalrResult.ToObject();
+                    taskCompletionSource.SetResult(updateCheckResult);
                 }
                 catch (Exception ex)
                 {
                     taskCompletionSource.SetException(ex);
                 }
-            });
-            BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesError" + guid, (error) =>
-            {
-                BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesComplete" + guid);
-                BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesError" + guid);
-                string message = "An error occurred in CheckForUpdatesAsync";
-                if (error != null && !string.IsNullOrEmpty(error.ToString()))
-                    message = JsonConvert.SerializeObject(error);
-                taskCompletionSource.SetException(new Exception(message));
-            });
-
-            BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdates", guid);
+            }
 
-            return taskCompletionSource.Task;
+            return await taskCompletionSource.Task;
         }
 
         /// 
@@ -523,40 +390,32 @@ public Task CheckForUpdatesAsync()
         /// This will immediately download an update, then install when the app quits.
         /// 
         /// 
-        public Task CheckForUpdatesAndNotifyAsync()
+        public async Task CheckForUpdatesAndNotifyAsync()
         {
             var taskCompletionSource = new TaskCompletionSource();
-            string guid = Guid.NewGuid().ToString();
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultJObject("autoUpdaterCheckForUpdatesAndNotify");
 
-            BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid, (updateCheckResult) =>
+            if (signalrResult["errno"] != null)
+            {
+                string message = "An error occurred in CheckForUpdatesAsync";
+                message = JsonConvert.SerializeObject(signalrResult);
+                taskCompletionSource.SetException(new Exception(message));
+            }
+            else
             {
                 try
                 {
-                    BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
-                    BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid);
-                    if (updateCheckResult == null)
-                        taskCompletionSource.SetResult(null);
-                    else
+                    var updateCheckResult = signalrResult.ToObject();
+                    taskCompletionSource.SetResult(updateCheckResult);
                         taskCompletionSource.SetResult(JObject.Parse(updateCheckResult.ToString()).ToObject());
                 }
                 catch (Exception ex)
                 {
                     taskCompletionSource.SetException(ex);
                 }
-            });
-            BridgeConnector.Socket.On("autoUpdaterCheckForUpdatesAndNotifyError" + guid, (error) =>
-            {
-                BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyComplete" + guid);
-                BridgeConnector.Socket.Off("autoUpdaterCheckForUpdatesAndNotifyError" + guid);
-                string message = "An error occurred in autoUpdaterCheckForUpdatesAndNotify";
-                if (error != null)
-                    message = JsonConvert.SerializeObject(error);
-                taskCompletionSource.SetException(new Exception(message));
-            });
-
-            BridgeConnector.Socket.Emit("autoUpdaterCheckForUpdatesAndNotify", guid);
+            }
 
-            return taskCompletionSource.Task;
+            return await taskCompletionSource.Task;
         }
 
         /// 
@@ -568,49 +427,28 @@ public Task CheckForUpdatesAndNotifyAsync()
         /// 
         /// *windows-only* Runs the installer in silent mode. Defaults to `false`.
         /// Run the app after finish even on silent install. Not applicable for macOS. Ignored if `isSilent` is set to `false`.
-        public void QuitAndInstall(bool isSilent = false, bool isForceRunAfter = false)
+        public async void QuitAndInstall(bool isSilent = false, bool isForceRunAfter = false)
         {
-            BridgeConnector.Socket.Emit("autoUpdaterQuitAndInstall", isSilent, isForceRunAfter);
+            await Electron.SignalrElectron.Clients.All.SendAsync("prepare-for-update", isSilent, isForceRunAfter);
+            await Electron.SignalrElectron.Clients.All.SendAsync("autoUpdaterQuitAndInstall", isSilent, isForceRunAfter);
         }
 
         /// 
         /// Start downloading update manually. You can use this method if "AutoDownload" option is set to "false".
         /// 
         /// Path to downloaded file.
-        public Task DownloadUpdateAsync()
+        public async Task DownloadUpdateAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-            string guid = Guid.NewGuid().ToString();
-
-            BridgeConnector.Socket.On("autoUpdaterDownloadUpdateComplete" + guid, (downloadedPath) =>
-            {
-                BridgeConnector.Socket.Off("autoUpdaterDownloadUpdateComplete" + guid);
-                taskCompletionSource.SetResult(downloadedPath.ToString());
-            });
-
-            BridgeConnector.Socket.Emit("autoUpdaterDownloadUpdate", guid);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultString("autoUpdaterDownloadUpdate");
         }
 
         /// 
         /// Feed URL.
         /// 
         /// Feed URL.
-        public Task GetFeedURLAsync()
+        public async Task GetFeedURLAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-            string guid = Guid.NewGuid().ToString();
-
-            BridgeConnector.Socket.On("autoUpdaterGetFeedURLComplete" + guid, (downloadedPath) =>
-            {
-                BridgeConnector.Socket.Off("autoUpdaterGetFeedURLComplete" + guid);
-                taskCompletionSource.SetResult(downloadedPath.ToString());
-            });
-
-            BridgeConnector.Socket.Emit("autoUpdaterGetFeedURL", guid);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultString("autoUpdaterGetFeedURL");
         }
 
         private readonly JsonSerializer _jsonSerializer = new JsonSerializer()
diff --git a/ElectronNET.API/BridgeConnector.cs b/ElectronNET.API/BridgeConnector.cs
deleted file mode 100644
index 08a84745..00000000
--- a/ElectronNET.API/BridgeConnector.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Quobject.SocketIoClientDotNet.Client;
-using System;
-
-namespace ElectronNET.API
-{
-    internal static class BridgeConnector
-    {
-        private static Socket _socket;
-        private static object _syncRoot = new object();
-
-        public static Socket Socket
-        {
-            get
-            {
-                if(_socket == null && HybridSupport.IsElectronActive)
-                {
-                    lock (_syncRoot)
-                    {
-                        if (_socket == null && HybridSupport.IsElectronActive)
-                        {
-                            _socket = IO.Socket("http://localhost:" + BridgeSettings.SocketPort);
-                            _socket.On(Socket.EVENT_CONNECT, () =>
-                            {
-                                Console.WriteLine("BridgeConnector connected!");
-                            });
-                        }
-                    }
-                }
-                else if(_socket == null && !HybridSupport.IsElectronActive)
-                {
-                    lock (_syncRoot)
-                    {
-                        if (_socket == null && !HybridSupport.IsElectronActive)
-                        {
-                            _socket = IO.Socket(new Uri("http://localhost"), new IO.Options { AutoConnect = false });
-                        }
-                    }
-                }
-
-                return _socket;
-            }
-        }
-    }
-}
diff --git a/ElectronNET.API/BridgeSettings.cs b/ElectronNET.API/BridgeSettings.cs
index 96a2653a..122f68af 100644
--- a/ElectronNET.API/BridgeSettings.cs
+++ b/ElectronNET.API/BridgeSettings.cs
@@ -11,7 +11,7 @@ public static class BridgeSettings
         /// 
         /// The socket port.
         /// 
-        public static string SocketPort { get; internal set; }
+        public static string SocketPort { get; set; }
 
         /// 
         /// Gets the web port.
@@ -19,6 +19,17 @@ public static class BridgeSettings
         /// 
         /// The web port.
         /// 
-        public static string WebPort { get; internal set; }
+        public static string WebPort { get; set; }
+
+        /// 
+        /// Manually set the port values instead of using the UseElectron extension method
+        /// 
+        /// 
+        /// 
+        public static void InitializePorts(int socketPort, int webPort)
+        {
+            SocketPort = socketPort.ToString();
+            WebPort    = webPort.ToString();
+        }
     }
 }
diff --git a/ElectronNET.API/BrowserView.cs b/ElectronNET.API/BrowserView.cs
index 96bddd7f..baa06488 100644
--- a/ElectronNET.API/BrowserView.cs
+++ b/ElectronNET.API/BrowserView.cs
@@ -1,4 +1,5 @@
 using ElectronNET.API.Entities;
+using Microsoft.AspNetCore.SignalR;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using Newtonsoft.Json.Serialization;
@@ -31,29 +32,19 @@ public class BrowserView
         /// 
         /// (experimental)
         /// 
-        public Rectangle Bounds
+        public async Task GetBoundsAsync()
         {
-            get
-            {
-                return Task.Run(() =>
-                {
-                    var taskCompletionSource = new TaskCompletionSource();
-
-                    BridgeConnector.Socket.On("browserView-getBounds-reply", (result) =>
-                    {
-                        BridgeConnector.Socket.Off("browserView-getBounds-reply");
-                        taskCompletionSource.SetResult((Rectangle)result);
-                    });
-
-                    BridgeConnector.Socket.Emit("browserView-getBounds", Id);
+            var signalrResult = await SignalrSerializeHelper.GetSignalrResultJObject("browserView-getBounds", Id);
+            return ((JObject)signalrResult).ToObject();
+        }
 
-                    return taskCompletionSource.Task;
-                }).Result;
-            }
-            set
-            {
-                BridgeConnector.Socket.Emit("browserView-setBounds", Id, JObject.FromObject(value, _jsonSerializer));
-            }
+        /// 
+        /// Set the bounds of the current view inside the window
+        /// 
+        /// 
+        public async void SetBounds(Rectangle value)
+        {
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserView-setBounds", Id, JObject.FromObject(value, _jsonSerializer));
         }
 
         /// 
@@ -72,9 +63,9 @@ internal BrowserView(int id)
         /// (experimental)
         /// 
         /// 
-        public void SetAutoResize(AutoResizeOptions options)
+        public async void SetAutoResize(AutoResizeOptions options)
         {
-            BridgeConnector.Socket.Emit("browserView-setAutoResize", Id, JObject.FromObject(options, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserView-setAutoResize", Id, JObject.FromObject(options, _jsonSerializer));
         }
 
         /// 
@@ -83,9 +74,9 @@ public void SetAutoResize(AutoResizeOptions options)
         /// (experimental)
         /// 
         /// Color in #aarrggbb or #argb form. The alpha channel is optional.
-        public void SetBackgroundColor(string color)
+        public async void SetBackgroundColor(string color)
         {
-            BridgeConnector.Socket.Emit("browserView-setBackgroundColor", Id, color);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserView-setBackgroundColor", Id, color);
         }
 
         private JsonSerializer _jsonSerializer = new JsonSerializer()
diff --git a/ElectronNET.API/BrowserWindow.cs b/ElectronNET.API/BrowserWindow.cs
index 2c4590ac..e9fe4f5a 100644
--- a/ElectronNET.API/BrowserWindow.cs
+++ b/ElectronNET.API/BrowserWindow.cs
@@ -1,5 +1,7 @@
 using ElectronNET.API.Entities;
 using ElectronNET.API.Extensions;
+using ElectronNET.API.Hubs;
+using Microsoft.AspNetCore.SignalR;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using Newtonsoft.Json.Serialization;
@@ -7,8 +9,11 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
 using System.Threading.Tasks;
 
+//TODO: Add setTrafficLightPosition and getTrafficLightPosition: https://www.electronjs.org/docs/api/browser-window#winsettrafficlightpositionposition-macos
+
 namespace ElectronNET.API
 {
     /// 
@@ -34,24 +39,21 @@ public event Action OnReadyToShow
             {
                 if (_readyToShow == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-ready-to-show" + Id, () =>
-                    {
-                        _readyToShow();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-ready-to-show", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-ready-to-show", Id);
                 }
                 _readyToShow += value;
             }
             remove
             {
                 _readyToShow -= value;
-
-                if (_readyToShow == null)
-                    BridgeConnector.Socket.Off("browserWindow-ready-to-show" + Id);
             }
         }
 
+        public void TriggerOnReadyToShow()
+        {
+            _readyToShow();
+        }
+
         private event Action _readyToShow;
 
         /// 
@@ -63,24 +65,21 @@ public event Action OnPageTitleUpdated
             {
                 if (_pageTitleUpdated == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-page-title-updated" + Id, (title) =>
-                    {
-                        _pageTitleUpdated(title.ToString());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-page-title-updated", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-page-title-updated", Id);
                 }
                 _pageTitleUpdated += value;
             }
             remove
             {
                 _pageTitleUpdated -= value;
-
-                if (_pageTitleUpdated == null)
-                    BridgeConnector.Socket.Off("browserWindow-page-title-updated" + Id);
             }
         }
 
+        public void TriggerOnPageTitleUpdated(string title)
+        {
+            _pageTitleUpdated(title);
+        }
+
         private event Action _pageTitleUpdated;
 
         /// 
@@ -92,24 +91,21 @@ public event Action OnClose
             {
                 if (_close == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-close" + Id, () =>
-                    {
-                        _close();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-close", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-close", Id);
                 }
                 _close += value;
             }
             remove
             {
                 _close -= value;
-
-                if (_close == null)
-                    BridgeConnector.Socket.Off("browserWindow-close" + Id);
             }
         }
 
+        public void TriggerOnClose()
+        {
+            _close();
+        }
+
         private event Action _close;
 
         /// 
@@ -123,21 +119,22 @@ public event Action OnClosed
             {
                 if (_closed == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-closed" + Id, () =>
-                    {
-                        _closed();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-closed", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-closed", Id);
                 }
                 _closed += value;
             }
             remove
             {
                 _closed -= value;
+            }
+        }
 
-                if (_closed == null)
-                    BridgeConnector.Socket.Off("browserWindow-closed" + Id);
+        public void TriggerOnClosed()
+        {
+            // Trigger only if we've a listener
+            if (_closed != null)
+            {
+                _closed();
             }
         }
 
@@ -146,30 +143,28 @@ public event Action OnClosed
         /// 
         /// Emitted when window session is going to end due to force shutdown or machine restart or session log off.
         /// 
+        [SupportedOSPlatform("windows")]
         public event Action OnSessionEnd
         {
             add
             {
                 if (_sessionEnd == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-session-end" + Id, () =>
-                    {
-                        _sessionEnd();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-session-end", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-session-end", Id);
                 }
                 _sessionEnd += value;
             }
             remove
             {
                 _sessionEnd -= value;
-
-                if (_sessionEnd == null)
-                    BridgeConnector.Socket.Off("browserWindow-session-end" + Id);
             }
         }
 
+        public void TriggerOnSessionEnd()
+        {
+            _sessionEnd();
+        }
+
         private event Action _sessionEnd;
 
         /// 
@@ -181,24 +176,21 @@ public event Action OnUnresponsive
             {
                 if (_unresponsive == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-unresponsive" + Id, () =>
-                    {
-                        _unresponsive();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-unresponsive", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-unresponsive", Id);
                 }
                 _unresponsive += value;
             }
             remove
             {
                 _unresponsive -= value;
-
-                if (_unresponsive == null)
-                    BridgeConnector.Socket.Off("browserWindow-unresponsive" + Id);
             }
         }
 
+        public void TriggerOnUnresponsive()
+        {
+            _unresponsive();
+        }
+
         private event Action _unresponsive;
 
         /// 
@@ -210,24 +202,21 @@ public event Action OnResponsive
             {
                 if (_responsive == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-responsive" + Id, () =>
-                    {
-                        _responsive();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-responsive", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-responsive", Id);
                 }
                 _responsive += value;
             }
             remove
             {
                 _responsive -= value;
-
-                if (_responsive == null)
-                    BridgeConnector.Socket.Off("browserWindow-responsive" + Id);
             }
         }
 
+        public void TriggerOnResponsive()
+        {
+            _responsive();
+        }
+
         private event Action _responsive;
 
         /// 
@@ -239,25 +228,22 @@ public event Action OnBlur
             {
                 if (_blur == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-blur" + Id, () =>
-                    {
-                        _blur();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-blur", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-blur", Id);
                 }
                 _blur += value;
             }
             remove
             {
                 _blur -= value;
-
-                if (_blur == null)
-                    BridgeConnector.Socket.Off("browserWindow-blur" + Id);
             }
         }
 
-        private event Action _blur;
+        public void TriggerOnBlur()
+        {
+            _blur();
+        }
+
+        public event Action _blur;
 
         /// 
         /// Emitted when the window gains focus.
@@ -268,24 +254,21 @@ public event Action OnFocus
             {
                 if (_focus == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-focus" + Id, () =>
-                    {
-                        _focus();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-focus", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-focus", Id);
                 }
                 _focus += value;
             }
             remove
             {
                 _focus -= value;
-
-                if (_focus == null)
-                    BridgeConnector.Socket.Off("browserWindow-focus" + Id);
             }
         }
 
+        public void TriggerOnFocus()
+        {
+            _focus();
+        }
+
         private event Action _focus;
 
         /// 
@@ -297,24 +280,21 @@ public event Action OnShow
             {
                 if (_show == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-show" + Id, () =>
-                    {
-                        _show();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-show", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-show", Id);
                 }
                 _show += value;
             }
             remove
             {
                 _show -= value;
-
-                if (_show == null)
-                    BridgeConnector.Socket.Off("browserWindow-show" + Id);
             }
         }
 
+        public void TriggerOnShow()
+        {
+            _show();
+        }
+
         private event Action _show;
 
         /// 
@@ -326,24 +306,21 @@ public event Action OnHide
             {
                 if (_hide == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-hide" + Id, () =>
-                    {
-                        _hide();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-hide", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-hide", Id);
                 }
                 _hide += value;
             }
             remove
             {
                 _hide -= value;
-
-                if (_hide == null)
-                    BridgeConnector.Socket.Off("browserWindow-hide" + Id);
             }
         }
 
+        public void TriggerOnHide()
+        {
+            _hide();
+        }
+
         private event Action _hide;
 
         /// 
@@ -355,24 +332,21 @@ public event Action OnMaximize
             {
                 if (_maximize == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-maximize" + Id, () =>
-                    {
-                        _maximize();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-maximize", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-maximize", Id);
                 }
                 _maximize += value;
             }
             remove
             {
                 _maximize -= value;
-
-                if (_maximize == null)
-                    BridgeConnector.Socket.Off("browserWindow-maximize" + Id);
             }
         }
 
+        public void TriggerOnMaximize()
+        {
+            _maximize();
+        }
+
         private event Action _maximize;
 
         /// 
@@ -384,24 +358,21 @@ public event Action OnUnmaximize
             {
                 if (_unmaximize == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-unmaximize" + Id, () =>
-                    {
-                        _unmaximize();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-unmaximize", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-unmaximize", Id);
                 }
                 _unmaximize += value;
             }
             remove
             {
                 _unmaximize -= value;
-
-                if (_unmaximize == null)
-                    BridgeConnector.Socket.Off("browserWindow-unmaximize" + Id);
             }
         }
 
+        public void TriggerOnUnmaximize()
+        {
+            _unmaximize();
+        }
+
         private event Action _unmaximize;
 
         /// 
@@ -413,24 +384,21 @@ public event Action OnMinimize
             {
                 if (_minimize == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-minimize" + Id, () =>
-                    {
-                        _minimize();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-minimize", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-minimize", Id);
                 }
                 _minimize += value;
             }
             remove
             {
                 _minimize -= value;
-
-                if (_minimize == null)
-                    BridgeConnector.Socket.Off("browserWindow-minimize" + Id);
             }
         }
 
+        public void TriggerOnMinimize()
+        {
+            _minimize();
+        }
+
         private event Action _minimize;
 
         /// 
@@ -442,53 +410,49 @@ public event Action OnRestore
             {
                 if (_restore == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-restore" + Id, () =>
-                    {
-                        _restore();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-restore", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-restore", Id);
                 }
                 _restore += value;
             }
             remove
             {
                 _restore -= value;
-
-                if (_restore == null)
-                    BridgeConnector.Socket.Off("browserWindow-restore" + Id);
             }
         }
 
+        public void TriggerOnRestore()
+        {
+            _restore();
+        }
+
         private event Action _restore;
 
         /// 
         /// Emitted when the window is being resized.
         /// 
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public event Action OnResize
         {
             add
             {
                 if (_resize == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-resize" + Id, () =>
-                    {
-                        _resize();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-resize", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-resize", Id);
                 }
                 _resize += value;
             }
             remove
             {
                 _resize -= value;
-
-                if (_resize == null)
-                    BridgeConnector.Socket.Off("browserWindow-resize" + Id);
             }
         }
 
+        public void TriggerOnResize()
+        {
+            _resize();
+        }
+
         private event Action _resize;
 
         /// 
@@ -496,59 +460,57 @@ public event Action OnResize
         /// 
         /// Note: On macOS this event is just an alias of moved.
         /// 
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public event Action OnMove
         {
             add
             {
                 if (_move == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-move" + Id, () =>
-                    {
-                        _move();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-move", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-move", Id);
                 }
                 _move += value;
             }
             remove
             {
                 _move -= value;
-
-                if (_move == null)
-                    BridgeConnector.Socket.Off("browserWindow-move" + Id);
             }
         }
 
+        public void TriggerOnMove()
+        {
+            _move();
+        }
+
         private event Action _move;
 
         /// 
-        /// macOS: Emitted once when the window is moved to a new position.
+        /// Emitted once when the window is moved to a new position.
         /// 
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public event Action OnMoved
         {
             add
             {
                 if (_moved == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-moved" + Id, () =>
-                    {
-                        _moved();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-moved", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-moved", Id);
                 }
                 _moved += value;
             }
             remove
             {
                 _moved -= value;
-
-                if (_moved == null)
-                    BridgeConnector.Socket.Off("browserWindow-moved" + Id);
             }
         }
 
+        public void TriggerOnMoved()
+        {
+            _moved();
+        }
+
         private event Action _moved;
 
         /// 
@@ -560,24 +522,21 @@ public event Action OnEnterFullScreen
             {
                 if (_enterFullScreen == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-enter-full-screen" + Id, () =>
-                    {
-                        _enterFullScreen();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-enter-full-screen", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-enter-full-screen", Id);
                 }
                 _enterFullScreen += value;
             }
             remove
             {
                 _enterFullScreen -= value;
-
-                if (_enterFullScreen == null)
-                    BridgeConnector.Socket.Off("browserWindow-enter-full-screen" + Id);
             }
         }
 
+        public void TriggerOnEnterFullScreen()
+        {
+            _enterFullScreen();
+        }
+
         private event Action _enterFullScreen;
 
         /// 
@@ -589,24 +548,21 @@ public event Action OnLeaveFullScreen
             {
                 if (_leaveFullScreen == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-leave-full-screen" + Id, () =>
-                    {
-                        _leaveFullScreen();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-leave-full-screen", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-leave-full-screen", Id);
                 }
                 _leaveFullScreen += value;
             }
             remove
             {
                 _leaveFullScreen -= value;
-
-                if (_leaveFullScreen == null)
-                    BridgeConnector.Socket.Off("browserWindow-leave-full-screen" + Id);
             }
         }
 
+        public void TriggerOnLeaveFullScreen()
+        {
+            _leaveFullScreen();
+        }
+
         private event Action _leaveFullScreen;
 
         /// 
@@ -618,24 +574,21 @@ public event Action OnEnterHtmlFullScreen
             {
                 if (_enterHtmlFullScreen == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-enter-html-full-screen" + Id, () =>
-                    {
-                        _enterHtmlFullScreen();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-enter-html-full-screen", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-enter-html-full-screen", Id);
                 }
                 _enterHtmlFullScreen += value;
             }
             remove
             {
                 _enterHtmlFullScreen -= value;
-
-                if (_enterHtmlFullScreen == null)
-                    BridgeConnector.Socket.Off("browserWindow-enter-html-full-screen" + Id);
             }
         }
 
+        public void TriggerOnEnterHtmlFullScreen()
+        {
+            _enterHtmlFullScreen();
+        }
+
         private event Action _enterHtmlFullScreen;
 
         /// 
@@ -647,24 +600,21 @@ public event Action OnLeaveHtmlFullScreen
             {
                 if (_leaveHtmlFullScreen == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-leave-html-full-screen" + Id, () =>
-                    {
-                        _leaveHtmlFullScreen();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-leave-html-full-screen", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-leave-html-full-screen", Id);
                 }
                 _leaveHtmlFullScreen += value;
             }
             remove
             {
                 _leaveHtmlFullScreen -= value;
-
-                if (_leaveHtmlFullScreen == null)
-                    BridgeConnector.Socket.Off("browserWindow-leave-html-full-screen" + Id);
             }
         }
 
+        public void TriggerOnLeaveHtmlFullScreen()
+        {
+            _leaveHtmlFullScreen();
+        }
+
         private event Action _leaveHtmlFullScreen;
 
         /// 
@@ -676,233 +626,218 @@ public event Action OnLeaveHtmlFullScreen
         /// and the APPCOMMAND_ prefix is stripped off.e.g.APPCOMMAND_BROWSER_BACKWARD 
         /// is emitted as browser-backward.
         /// 
+        [SupportedOSPlatform("macos")]
+        [SupportedOSPlatform("windows")]
         public event Action OnAppCommand
         {
             add
             {
                 if (_appCommand == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-app-command" + Id, (command) =>
-                    {
-                        _appCommand(command.ToString());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-app-command", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-app-command", Id);
                 }
                 _appCommand += value;
             }
             remove
             {
                 _appCommand -= value;
-
-                if (_appCommand == null)
-                    BridgeConnector.Socket.Off("browserWindow-app-command" + Id);
             }
         }
 
+        public void TriggerOnAppCommand(string command)
+        {
+            _appCommand(command);
+        }
+
         private event Action _appCommand;
 
         /// 
         /// Emitted when scroll wheel event phase has begun.
         /// 
+        [SupportedOSPlatform("macos")]
         public event Action OnScrollTouchBegin
         {
             add
             {
                 if (_scrollTouchBegin == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-scroll-touch-begin" + Id, () =>
-                    {
-                        _scrollTouchBegin();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-scroll-touch-begin", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-scroll-touch-begin", Id);
                 }
                 _scrollTouchBegin += value;
             }
             remove
             {
                 _scrollTouchBegin -= value;
-
-                if (_scrollTouchBegin == null)
-                    BridgeConnector.Socket.Off("browserWindow-scroll-touch-begin" + Id);
             }
         }
 
+        public void TriggerOnScrollTouchBegin()
+        {
+            _scrollTouchBegin();
+        }
+
         private event Action _scrollTouchBegin;
 
         /// 
         /// Emitted when scroll wheel event phase has ended.
         /// 
+        [SupportedOSPlatform("macos")]
         public event Action OnScrollTouchEnd
         {
             add
             {
                 if (_scrollTouchEnd == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-scroll-touch-end" + Id, () =>
-                    {
-                        _scrollTouchEnd();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-scroll-touch-end", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-scroll-touch-end", Id);
                 }
                 _scrollTouchEnd += value;
             }
             remove
             {
                 _scrollTouchEnd -= value;
-
-                if (_scrollTouchEnd == null)
-                    BridgeConnector.Socket.Off("browserWindow-scroll-touch-end" + Id);
             }
         }
 
+        public void TriggerOnScrollTouchEnd()
+        {
+            _scrollTouchEnd();
+        }
+
         private event Action _scrollTouchEnd;
 
         /// 
         /// Emitted when scroll wheel event phase filed upon reaching the edge of element.
         /// 
+        [SupportedOSPlatform("macos")]
         public event Action OnScrollTouchEdge
         {
             add
             {
                 if (_scrollTouchEdge == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-scroll-touch-edge" + Id, () =>
-                    {
-                        _scrollTouchEdge();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-scroll-touch-edge", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-scroll-touch-edge", Id);
                 }
                 _scrollTouchEdge += value;
             }
             remove
             {
                 _scrollTouchEdge -= value;
-
-                if (_scrollTouchEdge == null)
-                    BridgeConnector.Socket.Off("browserWindow-scroll-touch-edge" + Id);
             }
         }
 
+        public void TriggerOnScrollTouchEdge()
+        {
+            _scrollTouchEdge();
+        }
+
         private event Action _scrollTouchEdge;
 
         /// 
         /// Emitted on 3-finger swipe. Possible directions are up, right, down, left.
         /// 
+        [SupportedOSPlatform("macos")]
         public event Action OnSwipe
         {
             add
             {
                 if (_swipe == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-swipe" + Id, (direction) =>
-                    {
-                        _swipe(direction.ToString());
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-swipe", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-swipe", Id);
                 }
                 _swipe += value;
             }
             remove
             {
                 _swipe -= value;
-
-                if (_swipe == null)
-                    BridgeConnector.Socket.Off("browserWindow-swipe" + Id);
             }
         }
 
+        public void TriggerOnSwipe(string direction)
+        {
+            _swipe(direction);
+        }
+
         private event Action _swipe;
 
         /// 
         /// Emitted when the window opens a sheet.
         /// 
+        [SupportedOSPlatform("macos")]
         public event Action OnSheetBegin
         {
             add
             {
                 if (_sheetBegin == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-sheet-begin" + Id, () =>
-                    {
-                        _sheetBegin();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-sheet-begin", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-sheet-begin", Id);
                 }
                 _sheetBegin += value;
             }
             remove
             {
                 _sheetBegin -= value;
-
-                if (_sheetBegin == null)
-                    BridgeConnector.Socket.Off("browserWindow-sheet-begin" + Id);
             }
         }
 
+        public void TriggerOnSheetBegin()
+        {
+            _sheetBegin();
+        }
+
         private event Action _sheetBegin;
 
         /// 
         /// Emitted when the window has closed a sheet.
         /// 
+        [SupportedOSPlatform("macos")]
         public event Action OnSheetEnd
         {
             add
             {
                 if (_sheetEnd == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-sheet-end" + Id, () =>
-                    {
-                        _sheetEnd();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-sheet-end", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-sheet-end", Id);
                 }
                 _sheetEnd += value;
             }
             remove
             {
                 _sheetEnd -= value;
-
-                if (_sheetEnd == null)
-                    BridgeConnector.Socket.Off("browserWindow-sheet-end" + Id);
             }
         }
 
+        public void TriggerOnSheetEnd()
+        {
+            _sheetEnd();
+        }
+
         private event Action _sheetEnd;
 
         /// 
         /// Emitted when the native new tab button is clicked.
         /// 
+        [SupportedOSPlatform("macos")]
         public event Action OnNewWindowForTab
         {
             add
             {
                 if (_newWindowForTab == null)
                 {
-                    BridgeConnector.Socket.On("browserWindow-new-window-for-tab" + Id, () =>
-                    {
-                        _newWindowForTab();
-                    });
-
-                    BridgeConnector.Socket.Emit("register-browserWindow-new-window-for-tab", Id);
+                    Electron.SignalrElectron.Clients.All.SendAsync("register-browserWindow-new-window-for-tab", Id);
                 }
                 _newWindowForTab += value;
             }
             remove
             {
                 _newWindowForTab -= value;
-
-                if (_newWindowForTab == null)
-                    BridgeConnector.Socket.Off("browserWindow-new-window-for-tab" + Id);
             }
         }
 
+        public void TriggerOnNewWindowForTab()
+        {
+            _newWindowForTab();
+        }
+
         private event Action _newWindowForTab;
 
         internal BrowserWindow(int id) {
@@ -915,231 +850,187 @@ internal BrowserWindow(int id) {
         /// emitted for the web page, and close event will also not be emitted 
         /// for this window, but it guarantees the closed event will be emitted.
         /// 
-        public void Destroy()
+        public async void Destroy()
         {
-            BridgeConnector.Socket.Emit("browserWindowDestroy", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowDestroy", Id);
         }
 
         /// 
         /// Try to close the window. This has the same effect as a user manually 
         /// clicking the close button of the window. The web page may cancel the close though. 
         /// 
-        public void Close()
+        public async void Close()
         {
-            BridgeConnector.Socket.Emit("browserWindowClose", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowClose", Id);
         }
 
         /// 
         /// Focuses on the window.
         /// 
-        public void Focus()
+        public async void Focus()
         {
-            BridgeConnector.Socket.Emit("browserWindowFocus", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowFocus", Id);
         }
 
         /// 
         /// Removes focus from the window.
         /// 
-        public void Blur()
+        public async void Blur()
         {
-            BridgeConnector.Socket.Emit("browserWindowBlur", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowBlur", Id);
         }
 
         /// 
         /// Whether the window is focused.
         /// 
         /// 
-        public Task IsFocusedAsync()
+        public async Task IsFocusedAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isFocused-completed", (isFocused) => {
-                BridgeConnector.Socket.Off("browserWindow-isFocused-completed");
-
-                taskCompletionSource.SetResult((bool)isFocused);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsFocused", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsFocused", Id);
         }
 
         /// 
         /// Whether the window is destroyed.
         /// 
         /// 
-        public Task IsDestroyedAsync()
+        public async Task IsDestroyedAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isDestroyed-completed", (isDestroyed) => {
-                BridgeConnector.Socket.Off("browserWindow-isDestroyed-completed");
-
-                taskCompletionSource.SetResult((bool)isDestroyed);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsDestroyed", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsDestroyed", Id);
         }
 
         /// 
         /// Shows and gives focus to the window.
         /// 
-        public void Show()
+        public async void Show()
         {
-            BridgeConnector.Socket.Emit("browserWindowShow", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowShow", Id);
         }
 
         /// 
         /// Shows the window but doesn’t focus on it.
         /// 
-        public void ShowInactive()
+        public async void ShowInactive()
         {
-            BridgeConnector.Socket.Emit("browserWindowShowInactive", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowShowInactive", Id);
         }
 
         /// 
         /// Hides the window.
         /// 
-        public void Hide()
+        public async void Hide()
         {
-            BridgeConnector.Socket.Emit("browserWindowHide", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowHide", Id);
         }
 
         /// 
         /// Whether the window is visible to the user.
         /// 
         /// 
-        public Task IsVisibleAsync()
+        public async Task IsVisibleAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isVisible-completed", (isVisible) => {
-                BridgeConnector.Socket.Off("browserWindow-isVisible-completed");
-
-                taskCompletionSource.SetResult((bool)isVisible);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsVisible", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsVisible", Id);
         }
 
         /// 
         /// Whether current window is a modal window.
         /// 
         /// 
-        public Task IsModalAsync()
+        public async Task IsModalAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isModal-completed", (isModal) => {
-                BridgeConnector.Socket.Off("browserWindow-isModal-completed");
-
-                taskCompletionSource.SetResult((bool)isModal);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsModal", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsModal", Id);
         }
 
         /// 
         /// Maximizes the window. This will also show (but not focus) the window if it isn’t being displayed already.
         /// 
-        public void Maximize()
+        public async void Maximize()
         {
-            BridgeConnector.Socket.Emit("browserWindowMaximize", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowMaximize", Id);
         }
 
         /// 
         /// Unmaximizes the window.
         /// 
-        public void Unmaximize()
+        public async void Unmaximize()
         {
-            BridgeConnector.Socket.Emit("browserWindowUnmaximize", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowUnmaximize", Id);
         }
 
         /// 
         /// Whether the window is maximized.
         /// 
         /// 
-        public Task IsMaximizedAsync()
+        public async Task IsMaximizedAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isMaximized-completed", (isMaximized) => {
-                BridgeConnector.Socket.Off("browserWindow-isMaximized-completed");
-
-                taskCompletionSource.SetResult((bool)isMaximized);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsMaximized", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsMaximized", Id);
         }
 
         /// 
         /// Minimizes the window. On some platforms the minimized window will be shown in the Dock.
         /// 
-        public void Minimize()
+        public async void Minimize()
         {
-            BridgeConnector.Socket.Emit("browserWindowMinimize", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowMinimize", Id);
         }
 
         /// 
         /// Restores the window from minimized state to its previous state.
         /// 
-        public void Restore()
+        public async void Restore()
         {
-            BridgeConnector.Socket.Emit("browserWindowRestore", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowRestore", Id);
         }
 
         /// 
         /// Whether the window is minimized.
         /// 
         /// 
-        public Task IsMinimizedAsync()
+        public async Task IsMinimizedAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isMinimized-completed", (isMinimized) => {
-                BridgeConnector.Socket.Off("browserWindow-isMinimized-completed");
-
-                taskCompletionSource.SetResult((bool)isMinimized);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsMinimized", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsMinimized", Id);
         }
 
         /// 
         /// Sets whether the window should be in fullscreen mode.
         /// 
-        public void SetFullScreen(bool flag)
+        public async void SetFullScreen(bool flag)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetFullScreen", Id, flag);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetFullScreen", Id, flag);
+        }
+        
+        /// 
+        /// Sets whether the background color of the window
+        /// 
+        public async void SetBackgroundColor(string color)
+        {
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetBackgroundColor", Id, color);
         }
 
         /// 
         /// Whether the window is in fullscreen mode.
         /// 
         /// 
-        public Task IsFullScreenAsync()
+        public async Task IsFullScreenAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isFullScreen-completed", (isFullScreen) => {
-                BridgeConnector.Socket.Off("browserWindow-isFullScreen-completed");
-
-                taskCompletionSource.SetResult((bool)isFullScreen);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsFullScreen", Id);
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsFullScreen", Id);
+        }
 
-            return taskCompletionSource.Task;
+        /// 
+        /// This will make a window maintain an aspect ratio. The extra size allows a developer to have space, 
+        /// specified in pixels, not included within the aspect ratio calculations. This API already takes into
+        /// account the difference between a window’s size and its content size.
+        ///
+        /// Consider a normal window with an HD video player and associated controls.Perhaps there are 15 pixels
+        /// of controls on the left edge, 25 pixels of controls on the right edge and 50 pixels of controls below
+        /// the player. In order to maintain a 16:9 aspect ratio (standard aspect ratio for HD @1920x1080) within
+        /// the player itself we would call this function with arguments of 16/9 and[40, 50]. The second argument
+        /// doesn’t care where the extra width and height are within the content view–only that they exist. Just 
+        /// sum any extra width and height areas you have within the overall content view.
+        /// 
+        /// The aspect ratio to maintain for some portion of the content view.
+        public async void SetAspectRatio(int aspectRatio)
+        {
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetAspectRatio", Id, aspectRatio, JObject.FromObject(new Size() { Height = 0, Width = 0 }, _jsonSerializer));
         }
 
         /// 
@@ -1156,9 +1047,10 @@ public Task IsFullScreenAsync()
         /// 
         /// The aspect ratio to maintain for some portion of the content view.
         /// The extra size not to be included while maintaining the aspect ratio.
-        public void SetAspectRatio(int aspectRatio, Size extraSize)
+        [SupportedOSPlatform("macos")]
+        public async void SetAspectRatio(int aspectRatio, Size extraSize)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetAspectRatio", Id, aspectRatio, JObject.FromObject(extraSize, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetAspectRatio", Id, aspectRatio, JObject.FromObject(extraSize, _jsonSerializer));
         }
 
         /// 
@@ -1167,9 +1059,10 @@ public void SetAspectRatio(int aspectRatio, Size extraSize)
         /// The absolute path to the file to preview with QuickLook. This is important as 
         /// Quick Look uses the file name and file extension on the path to determine the content type of the 
         /// file to open.
-        public void PreviewFile(string path)
+        [SupportedOSPlatform("macos")]
+        public async void PreviewFile(string path)
         {
-            BridgeConnector.Socket.Emit("browserWindowPreviewFile", Id, path);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowPreviewFile", Id, path);
         }
 
         /// 
@@ -1180,26 +1073,28 @@ public void PreviewFile(string path)
         /// file to open.
         /// The name of the file to display on the Quick Look modal view. This is 
         /// purely visual and does not affect the content type of the file. Defaults to path.
-        public void PreviewFile(string path, string displayname)
+        [SupportedOSPlatform("macos")]
+        public async void PreviewFile(string path, string displayname)
         {
-            BridgeConnector.Socket.Emit("browserWindowPreviewFile", Id, path, displayname);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowPreviewFile", Id, path, displayname);
         }
 
         /// 
         /// Closes the currently open Quick Look panel.
         /// 
-        public void CloseFilePreview()
+        [SupportedOSPlatform("macos")]
+        public async void CloseFilePreview()
         {
-            BridgeConnector.Socket.Emit("browserWindowCloseFilePreview", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowCloseFilePreview", Id);
         }
 
         /// 
         /// Resizes and moves the window to the supplied bounds
         /// 
         /// 
-        public void SetBounds(Rectangle bounds)
+        public async void SetBounds(Rectangle bounds)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetBounds", Id, JObject.FromObject(bounds, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetBounds", Id, JObject.FromObject(bounds, _jsonSerializer));
         }
 
         /// 
@@ -1207,37 +1102,29 @@ public void SetBounds(Rectangle bounds)
         /// 
         /// 
         /// 
-        public void SetBounds(Rectangle bounds, bool animate)
+        [SupportedOSPlatform("macos")]
+        public async void SetBounds(Rectangle bounds, bool animate)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetBounds", Id, JObject.FromObject(bounds, _jsonSerializer), animate);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetBounds", Id, JObject.FromObject(bounds, _jsonSerializer), animate);
         }
 
         /// 
         /// Gets the bounds asynchronous.
         /// 
         /// 
-        public Task GetBoundsAsync()
+        public async Task GetBoundsAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getBounds-completed", (getBounds) => {
-                BridgeConnector.Socket.Off("browserWindow-getBounds-completed");
-
-                taskCompletionSource.SetResult(((JObject)getBounds).ToObject());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetBounds", Id);
-
-            return taskCompletionSource.Task;
+            var result = await SignalrSerializeHelper.GetSignalrResultJObject("browserWindowGetBounds", Id);
+            return result.ToObject();
         }
 
         /// 
         /// Resizes and moves the window’s client area (e.g. the web page) to the supplied bounds.
         /// 
         /// 
-        public void SetContentBounds(Rectangle bounds)
+        public async void SetContentBounds(Rectangle bounds)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetContentBounds", Id, JObject.FromObject(bounds, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetContentBounds", Id, JObject.FromObject(bounds, _jsonSerializer));
         }
 
         /// 
@@ -1245,28 +1132,20 @@ public void SetContentBounds(Rectangle bounds)
         /// 
         /// 
         /// 
-        public void SetContentBounds(Rectangle bounds, bool animate)
+        [SupportedOSPlatform("macos")]
+        public async void SetContentBounds(Rectangle bounds, bool animate)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetContentBounds", Id, JObject.FromObject(bounds, _jsonSerializer), animate);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetContentBounds", Id, JObject.FromObject(bounds, _jsonSerializer), animate);
         }
 
         /// 
         /// Gets the content bounds asynchronous.
         /// 
         /// 
-        public Task GetContentBoundsAsync()
+        public async Task GetContentBoundsAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getContentBounds-completed", (getContentBounds) => {
-                BridgeConnector.Socket.Off("browserWindow-getContentBounds-completed");
-
-                taskCompletionSource.SetResult(((JObject)getContentBounds).ToObject());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetContentBounds", Id);
-
-            return taskCompletionSource.Task;
+            var result = await SignalrSerializeHelper.GetSignalrResultJObject("browserWindowGetContentBounds", Id);
+            return result.ToObject();
         }
 
         /// 
@@ -1274,9 +1153,9 @@ public Task GetContentBoundsAsync()
         /// 
         /// 
         /// 
-        public void SetSize(int width, int height)
+        public async void SetSize(int width, int height)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetSize", Id, width, height);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetSize", Id, width, height);
         }
 
         /// 
@@ -1285,28 +1164,19 @@ public void SetSize(int width, int height)
         /// 
         /// 
         /// 
-        public void SetSize(int width, int height, bool animate)
+        [SupportedOSPlatform("macos")]
+        public async void SetSize(int width, int height, bool animate)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetSize", Id, width, height, animate);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetSize", Id, width, height, animate);
         }
 
         /// 
         /// Contains the window’s width and height.
         /// 
         /// 
-        public Task GetSizeAsync()
+        public async Task GetSizeAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getSize-completed", (size) => {
-                BridgeConnector.Socket.Off("browserWindow-getSize-completed");
-
-                taskCompletionSource.SetResult(((JArray)size).ToObject());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetSize", Id);
-
-            return taskCompletionSource.Task;
+            return (await SignalrSerializeHelper.GetSignalrResultJArray("browserWindowGetSize", Id)).ToObject();
         }
 
         /// 
@@ -1314,9 +1184,9 @@ public Task GetSizeAsync()
         /// 
         /// 
         /// 
-        public void SetContentSize(int width, int height)
+        public async void SetContentSize(int width, int height)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetContentSize", Id, width, height);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetContentSize", Id, width, height);
         }
 
         /// 
@@ -1325,28 +1195,19 @@ public void SetContentSize(int width, int height)
         /// 
         /// 
         /// 
-        public void SetContentSize(int width, int height, bool animate)
+        [SupportedOSPlatform("macos")]
+        public async void SetContentSize(int width, int height, bool animate)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetContentSize", Id, width, height, animate);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetContentSize", Id, width, height, animate);
         }
 
         /// 
         /// Contains the window’s client area’s width and height.
         /// 
         /// 
-        public Task GetContentSizeAsync()
+        public async Task GetContentSizeAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getContentSize-completed", (size) => {
-                BridgeConnector.Socket.Off("browserWindow-getContentSize-completed");
-
-                taskCompletionSource.SetResult(((JArray)size).ToObject());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetContentSize", Id);
-
-            return taskCompletionSource.Task;
+            return (await SignalrSerializeHelper.GetSignalrResultJArray("browserWindowGetContentSize", Id)).ToObject();
         }
 
         /// 
@@ -1354,28 +1215,18 @@ public Task GetContentSizeAsync()
         /// 
         /// 
         /// 
-        public void SetMinimumSize(int width, int height)
+        public async void SetMinimumSize(int width, int height)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetMinimumSize", Id, width, height);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetMinimumSize", Id, width, height);
         }
 
         /// 
         /// Contains the window’s minimum width and height.
         /// 
         /// 
-        public Task GetMinimumSizeAsync()
+        public async Task GetMinimumSizeAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getMinimumSize-completed", (size) => {
-                BridgeConnector.Socket.Off("browserWindow-getMinimumSize-completed");
-
-                taskCompletionSource.SetResult(((JArray)size).ToObject());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetMinimumSize", Id);
-
-            return taskCompletionSource.Task;
+            return (await SignalrSerializeHelper.GetSignalrResultJArray("browserWindowGetMinimumSize", Id)).ToObject();
         }
 
         /// 
@@ -1383,204 +1234,142 @@ public Task GetMinimumSizeAsync()
         /// 
         /// 
         /// 
-        public void SetMaximumSize(int width, int height)
+        public async void SetMaximumSize(int width, int height)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetMaximumSize", Id, width, height);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetMaximumSize", Id, width, height);
         }
 
         /// 
         /// Contains the window’s maximum width and height.
         /// 
         /// 
-        public Task GetMaximumSizeAsync()
+        public async Task GetMaximumSizeAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getMaximumSize-completed", (size) => {
-                BridgeConnector.Socket.Off("browserWindow-getMaximumSize-completed");
-
-                taskCompletionSource.SetResult(((JArray)size).ToObject());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetMaximumSize", Id);
-
-            return taskCompletionSource.Task;
+            return (await SignalrSerializeHelper.GetSignalrResultJArray("browserWindowGetMaximumSize", Id)).ToObject();
         }
 
         /// 
         /// Sets whether the window can be manually resized by user.
         /// 
         /// 
-        public void SetResizable(bool resizable)
+        public async void SetResizable(bool resizable)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetResizable", Id, resizable);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetResizable", Id, resizable);
         }
 
         /// 
         /// Whether the window can be manually resized by user.
         /// 
         /// 
-        public Task IsResizableAsync()
+        public async Task IsResizableAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isResizable-completed", (resizable) => {
-                BridgeConnector.Socket.Off("browserWindow-isResizable-completed");
-
-                taskCompletionSource.SetResult((bool)resizable);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsResizable", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsResizable", Id);
         }
 
         /// 
         /// Sets whether the window can be moved by user. On Linux does nothing.
         /// 
         /// 
-        public void SetMovable(bool movable)
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async void SetMovable(bool movable)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetMovable", Id, movable);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetMovable", Id, movable);
         }
 
         /// 
         /// Whether the window can be moved by user.
-        /// 
-        /// On Linux always returns true.
         /// 
         /// On Linux always returns true.
-        public Task IsMovableAsync()
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async Task IsMovableAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isMovable-completed", (movable) => {
-                BridgeConnector.Socket.Off("browserWindow-isMovable-completed");
-
-                taskCompletionSource.SetResult((bool)movable);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsMovable", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsMovable", Id);
         }
 
         /// 
         /// Sets whether the window can be manually minimized by user. On Linux does nothing.
         /// 
         /// 
-        public void SetMinimizable(bool minimizable)
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async void SetMinimizable(bool minimizable)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetMinimizable", Id, minimizable);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetMinimizable", Id, minimizable);
         }
 
         /// 
         /// Whether the window can be manually minimized by user.
-        /// 
-        /// On Linux always returns true.
         /// 
         /// On Linux always returns true.
-        public Task IsMinimizableAsync()
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async Task IsMinimizableAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isMinimizable-completed", (minimizable) => {
-                BridgeConnector.Socket.Off("browserWindow-isMinimizable-completed");
-
-                taskCompletionSource.SetResult((bool)minimizable);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsMinimizable", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsMinimizable", Id);
         }
 
         /// 
         /// Sets whether the window can be manually maximized by user. On Linux does nothing.
         /// 
         /// 
-        public void SetMaximizable(bool maximizable)
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async void SetMaximizable(bool maximizable)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetMaximizable", Id, maximizable);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetMaximizable", Id, maximizable);
         }
 
         /// 
         /// Whether the window can be manually maximized by user.
-        /// 
-        /// On Linux always returns true.
         /// 
         /// On Linux always returns true.
-        public Task IsMaximizableAsync()
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async Task IsMaximizableAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isMaximizable-completed", (maximizable) => {
-                BridgeConnector.Socket.Off("browserWindow-isMaximizable-completed");
-
-                taskCompletionSource.SetResult((bool)maximizable);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsMaximizable", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsMaximizable", Id);
         }
 
         /// 
         /// Sets whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
         /// 
         /// 
-        public void SetFullScreenable(bool fullscreenable)
+        public async void SetFullScreenable(bool fullscreenable)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetFullScreenable", Id, fullscreenable);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetFullScreenable", Id, fullscreenable);
         }
 
         /// 
         /// Whether the maximize/zoom window button toggles fullscreen mode or maximizes the window.
         /// 
         /// 
-        public Task IsFullScreenableAsync()
+        public async Task IsFullScreenableAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isFullScreenable-completed", (fullscreenable) => {
-                BridgeConnector.Socket.Off("browserWindow-isFullScreenable-completed");
-
-                taskCompletionSource.SetResult((bool)fullscreenable);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsFullScreenable", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsFullScreenable", Id);
         }
 
         /// 
         /// Sets whether the window can be manually closed by user. On Linux does nothing.
         /// 
         /// 
-        public void SetClosable(bool closable)
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async void SetClosable(bool closable)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetClosable", Id, closable);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetClosable", Id, closable);
         }
 
         /// 
         /// Whether the window can be manually closed by user.
-        /// 
-        /// On Linux always returns true.
         /// 
         /// On Linux always returns true.
-        public Task IsClosableAsync()
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async Task IsClosableAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isClosable-completed", (closable) => {
-                BridgeConnector.Socket.Off("browserWindow-isClosable-completed");
-
-                taskCompletionSource.SetResult((bool)closable);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsClosable", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsClosable", Id);
         }
 
         /// 
@@ -1589,9 +1378,9 @@ public Task IsClosableAsync()
         /// window which can not be focused on.
         /// 
         /// 
-        public void SetAlwaysOnTop(bool flag)
+        public async void SetAlwaysOnTop(bool flag)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetAlwaysOnTop", Id, flag);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetAlwaysOnTop", Id, flag);
         }
 
         /// 
@@ -1603,9 +1392,11 @@ public void SetAlwaysOnTop(bool flag)
         /// Values include normal, floating, torn-off-menu, modal-panel, main-menu, 
         /// status, pop-up-menu and screen-saver. The default is floating. 
         /// See the macOS docs
-        public void SetAlwaysOnTop(bool flag, OnTopLevel level)
+        [SupportedOSPlatform("windows")]
+        [SupportedOSPlatform("macos")]
+        public async void SetAlwaysOnTop(bool flag, OnTopLevel level)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetAlwaysOnTop", Id, flag, level.GetDescription());
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetAlwaysOnTop", Id, flag, level.GetDescription());
         }
 
         /// 
@@ -1619,36 +1410,27 @@ public void SetAlwaysOnTop(bool flag, OnTopLevel level)
         /// See the macOS docs
         /// The number of layers higher to set this window relative to the given level. 
         /// The default is 0. Note that Apple discourages setting levels higher than 1 above screen-saver.
-        public void SetAlwaysOnTop(bool flag, OnTopLevel level, int relativeLevel)
+        [SupportedOSPlatform("macos")]
+        public async void SetAlwaysOnTop(bool flag, OnTopLevel level, int relativeLevel)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetAlwaysOnTop", Id, flag, level.GetDescription(), relativeLevel);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetAlwaysOnTop", Id, flag, level.GetDescription(), relativeLevel);
         }
 
         /// 
         /// Whether the window is always on top of other windows.
         /// 
         /// 
-        public Task IsAlwaysOnTopAsync()
+        public async Task IsAlwaysOnTopAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isAlwaysOnTop-completed", (isAlwaysOnTop) => {
-                BridgeConnector.Socket.Off("browserWindow-isAlwaysOnTop-completed");
-
-                taskCompletionSource.SetResult((bool)isAlwaysOnTop);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsAlwaysOnTop", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsAlwaysOnTop", Id);
         }
 
         /// 
         /// Moves window to the center of the screen.
         /// 
-        public void Center()
+        public async void Center()
         {
-            BridgeConnector.Socket.Emit("browserWindowCenter", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowCenter", Id);
         }
 
         /// 
@@ -1662,10 +1444,10 @@ public void SetPosition(int x, int y)
             // https://github.com/electron/electron/issues/4045
             if (isWindows10())
             {
-                x = x - 7;
+                x -= 7;
             }
 
-            BridgeConnector.Socket.Emit("browserWindowSetPosition", Id, x, y);
+            Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetPosition", Id, x, y);
         }
 
         /// 
@@ -1674,49 +1456,40 @@ public void SetPosition(int x, int y)
         /// 
         /// 
         /// 
+        [SupportedOSPlatform("macos")]
         public void SetPosition(int x, int y, bool animate)
         {
             // Workaround Windows 10 / Electron Bug
             // https://github.com/electron/electron/issues/4045
             if (isWindows10())
             {
-                x = x - 7;
+                x -= 7;
             }
 
-            BridgeConnector.Socket.Emit("browserWindowSetPosition", Id, x, y, animate);
+            Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetPosition", Id, x, y, animate);
         }
 
         private bool isWindows10()
         {
-            return RuntimeInformation.OSDescription.Contains("Windows 10");
+            return OperatingSystem.IsWindowsVersionAtLeast(10);
         }
 
         /// 
         /// Contains the window’s current position.
         /// 
         /// 
-        public Task GetPositionAsync()
+        public async Task GetPositionAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getPosition-completed", (position) => {
-                BridgeConnector.Socket.Off("browserWindow-getPosition-completed");
-
-                taskCompletionSource.SetResult(((JArray)position).ToObject());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetPosition", Id);
-
-            return taskCompletionSource.Task;
+            return (await SignalrSerializeHelper.GetSignalrResultJArray("browserWindowGetPosition", Id)).ToObject();
         }
 
         /// 
         /// Changes the title of native window to title.
         /// 
         /// 
-        public void SetTitle(string title)
+        public async void SetTitle(string title)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetTitle", Id, title);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetTitle", Id, title);
         }
 
         /// 
@@ -1725,19 +1498,9 @@ public void SetTitle(string title)
         /// Note: The title of web page can be different from the title of the native window.
         /// 
         /// 
-        public Task GetTitleAsync()
+        public async Task GetTitleAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getTitle-completed", (title) => {
-                BridgeConnector.Socket.Off("browserWindow-getTitle-completed");
-
-                taskCompletionSource.SetResult(title.ToString());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetTitle", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultString("browserWindowGetTitle", Id);
         }
 
         /// 
@@ -1746,9 +1509,10 @@ public Task GetTitleAsync()
         /// but you may want to display them beneath a HTML-rendered toolbar.
         /// 
         /// 
-        public void SetSheetOffset(float offsetY)
+        [SupportedOSPlatform("macos")]
+        public async void SetSheetOffset(float offsetY)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetSheetOffset", Id, offsetY);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetSheetOffset", Id, offsetY);
         }
 
         /// 
@@ -1758,74 +1522,55 @@ public void SetSheetOffset(float offsetY)
         /// 
         /// 
         /// 
-        public void SetSheetOffset(float offsetY, float offsetX)
+        [SupportedOSPlatform("macos")]
+        public async void SetSheetOffset(float offsetY, float offsetX)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetSheetOffset", Id, offsetY, offsetX);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetSheetOffset", Id, offsetY, offsetX);
         }
 
         /// 
         /// Starts or stops flashing the window to attract user’s attention.
         /// 
         /// 
-        public void FlashFrame(bool flag)
+        public async void FlashFrame(bool flag)
         {
-            BridgeConnector.Socket.Emit("browserWindowFlashFrame", Id, flag);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowFlashFrame", Id, flag);
         }
 
         /// 
         /// Makes the window not show in the taskbar.
         /// 
         /// 
-        public void SetSkipTaskbar(bool skip)
+        public async void SetSkipTaskbar(bool skip)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetSkipTaskbar", Id, skip);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetSkipTaskbar", Id, skip);
         }
 
         /// 
         /// Enters or leaves the kiosk mode.
         /// 
         /// 
-        public void SetKiosk(bool flag)
+        public async void SetKiosk(bool flag)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetKiosk", Id, flag);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetKiosk", Id, flag);
         }
 
         /// 
         /// Whether the window is in kiosk mode.
         /// 
         /// 
-        public Task IsKioskAsync()
+        public async Task IsKioskAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isKiosk-completed", (isKiosk) => {
-                BridgeConnector.Socket.Off("browserWindow-isKiosk-completed");
-
-                taskCompletionSource.SetResult((bool)isKiosk);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsKiosk", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsKiosk", Id);
         }
 
         /// 
         /// Returns the native type of the handle is HWND on Windows, NSView* on macOS, and Window (unsigned long) on Linux.
         /// 
         /// string of the native handle obtained, HWND on Windows, NSView* on macOS, and Window (unsigned long) on Linux.
-        public Task GetNativeWindowHandle()
+        public async Task GetNativeWindowHandle()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getNativeWindowHandle-completed", (nativeWindowHandle) =>
-            {
-                BridgeConnector.Socket.Off("browserWindow-getNativeWindowHandle-completed");
-                taskCompletionSource.SetResult(nativeWindowHandle.ToString());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetNativeWindowHandle", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultString("browserWindowGetNativeWindowHandle", Id);
         }
 
         /// 
@@ -1833,28 +1578,20 @@ public Task GetNativeWindowHandle()
         /// and the icon of the file will show in window’s title bar.
         /// 
         /// 
-        public void SetRepresentedFilename(string filename)
+        [SupportedOSPlatform("macos")]
+        public async void SetRepresentedFilename(string filename)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetRepresentedFilename", Id, filename);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetRepresentedFilename", Id, filename);
         }
 
         /// 
         /// The pathname of the file the window represents.
         /// 
         /// 
-        public Task GetRepresentedFilenameAsync()
+        [SupportedOSPlatform("macos")]
+        public async Task GetRepresentedFilenameAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-getRepresentedFilename-completed", (pathname) => {
-                BridgeConnector.Socket.Off("browserWindow-getRepresentedFilename-completed");
-
-                taskCompletionSource.SetResult(pathname.ToString());
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowGetRepresentedFilename", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultString("browserWindowGetRepresentedFilename", Id);
         }
 
         /// 
@@ -1862,44 +1599,36 @@ public Task GetRepresentedFilenameAsync()
         /// and the icon in title bar will become gray when set to true.
         /// 
         /// 
-        public void SetDocumentEdited(bool edited)
+        [SupportedOSPlatform("macos")]
+        public async void SetDocumentEdited(bool edited)
         {
-            BridgeConnector.Socket.Emit("browserWindowSetDocumentEdited", Id, edited);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowSetDocumentEdited", Id, edited);
         }
 
         /// 
         /// Whether the window’s document has been edited.
         /// 
         /// 
-        public Task IsDocumentEditedAsync()
+        [SupportedOSPlatform("macos")]
+        public async Task IsDocumentEditedAsync()
         {
-            var taskCompletionSource = new TaskCompletionSource();
-
-            BridgeConnector.Socket.On("browserWindow-isDocumentEdited-completed", (edited) => {
-                BridgeConnector.Socket.Off("browserWindow-isDocumentEdited-completed");
-
-                taskCompletionSource.SetResult((bool)edited);
-            });
-
-            BridgeConnector.Socket.Emit("browserWindowIsDocumentEdited", Id);
-
-            return taskCompletionSource.Task;
+            return await SignalrSerializeHelper.GetSignalrResultBool("browserWindowIsDocumentEdited", Id);
         }
 
         /// 
         /// Focuses the on web view.
         /// 
-        public void FocusOnWebView()
+        public async void FocusOnWebView()
         {
-            BridgeConnector.Socket.Emit("browserWindowFocusOnWebView", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowFocusOnWebView", Id);
         }
 
         /// 
         /// Blurs the web view.
         /// 
-        public void BlurWebView()
+        public async void BlurWebView()
         {
-            BridgeConnector.Socket.Emit("browserWindowBlurWebView", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowBlurWebView", Id);
         }
 
         /// 
@@ -1907,9 +1636,9 @@ public void BlurWebView()
         /// a path to a local HTML file using the file:// protocol.
         /// 
         /// 
-        public void LoadURL(string url)
+        public async void LoadURL(string url)
         {
-            BridgeConnector.Socket.Emit("browserWindowLoadURL", Id, url);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowLoadURL", Id, url);
         }
 
         /// 
@@ -1918,17 +1647,17 @@ public void LoadURL(string url)
         /// 
         /// 
         /// 
-        public void LoadURL(string url, LoadURLOptions options)
+        public async void LoadURL(string url, LoadURLOptions options)
         {
-            BridgeConnector.Socket.Emit("browserWindowLoadURL", Id, url, JObject.FromObject(options, _jsonSerializer));
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowLoadURL", Id, url, JObject.FromObject(options, _jsonSerializer));
         }
 
         /// 
         /// Same as webContents.reload.
         /// 
-        public void Reload()
+        public async void Reload()
         {
-            BridgeConnector.Socket.Emit("browserWindowReload", Id);
+            await Electron.SignalrElectron.Clients.All.SendAsync("browserWindowReload", Id);
         }
 
         /// 
@@ -1938,32 +1667,38 @@ public void Reload()
         /// The menu items.
         /// 
         public IReadOnlyCollection