diff --git a/Ryujinx.Audio/Renderers/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/Renderers/OpenAL/OpenALAudioOut.cs
index 30b325a51..ea5ce6214 100644
--- a/Ryujinx.Audio/Renderers/OpenAL/OpenALAudioOut.cs
+++ b/Ryujinx.Audio/Renderers/OpenAL/OpenALAudioOut.cs
@@ -101,6 +101,7 @@ namespace Ryujinx.Audio
             }
 
             _tracks.Clear();
+            _context.Dispose();
         }
 
         /// <summary>
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index a2bff7f62..f8d2ed71b 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -107,6 +107,7 @@ namespace Ryujinx.HLE.HOS
         public Keyset KeySet => Device.FileSystem.KeySet;
 
         private bool _hasStarted;
+        private bool _isDisposed;
 
         public BlitStruct<ApplicationControlProperty> ControlData { get; set; }
 
@@ -740,8 +741,10 @@ namespace Ryujinx.HLE.HOS
 
         protected virtual void Dispose(bool disposing)
         {
-            if (disposing)
+            if (!_isDisposed && disposing)
             {
+                _isDisposed = true;
+
                 KProcess terminationProcess = new KProcess(this);
 
                 KThread terminationThread = new KThread(this);
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
index f987c83c0..7807ec5a6 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
@@ -1131,5 +1131,10 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
         {
             throw new UndefinedInstructionException(e.Address, e.OpCode);
         }
+
+        protected override void Destroy()
+        {
+            CpuMemory.Dispose();
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
index c4bd781d4..53eb5bdc9 100644
--- a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
@@ -1141,6 +1141,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
         {
             Owner.Translator.Execute(Context, entrypoint);
 
+            Context.Dispose();
+
             ThreadExit();
         }
 
diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs
index 5ce33a9dd..24fbb9b8b 100644
--- a/Ryujinx/Program.cs
+++ b/Ryujinx/Program.cs
@@ -51,7 +51,7 @@ namespace Ryujinx
             string userProfilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch", "prod.keys");
             if (!File.Exists(appDataPath) && !File.Exists(userProfilePath) && !Migration.IsMigrationNeeded())
             {
-                GtkDialog.CreateErrorDialog("Key file was not found. Please refer to `KEYS.md` for more info");
+                GtkDialog.CreateWarningDialog("Key file was not found", "Please refer to `KEYS.md` for more info");
             }
 
             MainWindow mainWindow = new MainWindow();
diff --git a/Ryujinx/Ui/GtkDialog.cs b/Ryujinx/Ui/GtkDialog.cs
index 7f6be8dc7..b4e9fa1ca 100644
--- a/Ryujinx/Ui/GtkDialog.cs
+++ b/Ryujinx/Ui/GtkDialog.cs
@@ -5,19 +5,29 @@ namespace Ryujinx.Ui
 {
     internal class GtkDialog
     {
-        internal static void CreateErrorDialog(string errorMessage)
+        internal static void CreateDialog(string title, string text, string secondaryText)
         {
             MessageDialog errorDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Error, ButtonsType.Ok, null)
             {
-                Title          = "Ryujinx - Error",
+                Title          = title,
                 Icon           = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
-                Text           = "Ryujinx has encountered an error",
-                SecondaryText  = errorMessage,
+                Text           = text,
+                SecondaryText  = secondaryText,
                 WindowPosition = WindowPosition.Center
             };
             errorDialog.SetSizeRequest(100, 20);
             errorDialog.Run();
             errorDialog.Dispose();
         }
+
+        internal static void CreateWarningDialog(string text, string secondaryText)
+        {
+            CreateDialog("Ryujinx - Warning", text, secondaryText);
+        }
+
+        internal static void CreateErrorDialog(string errorMessage)
+        {
+            CreateDialog("Ryujinx - Error", "Ryujinx has encountered an error", errorMessage);
+        }
     }
 }
diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs
index 84c736bef..734103fed 100644
--- a/Ryujinx/Ui/MainWindow.cs
+++ b/Ryujinx/Ui/MainWindow.cs
@@ -32,6 +32,8 @@ namespace Ryujinx.Ui
 
         private static GlScreen _screen;
 
+        private static AutoResetEvent _screenExitStatus = new AutoResetEvent(false);
+
         private static ListStore _tableStore;
 
         private static bool _updatingGameTable;
@@ -278,7 +280,7 @@ namespace Ryujinx.Ui
         {
             if (_gameLoaded)
             {
-                GtkDialog.CreateErrorDialog("A game has already been loaded. Please close the emulator and try again");
+                GtkDialog.CreateDialog("Ryujinx", "A game has already been loaded", "Please close it first and try again.");
             }
             else
             {
@@ -347,6 +349,8 @@ namespace Ryujinx.Ui
 
                 _emulationContext = device;
 
+                _screenExitStatus.Reset();
+
 #if MACOS_BUILD
                 CreateGameWindow(device);
 #else
@@ -393,6 +397,8 @@ namespace Ryujinx.Ui
 
             DiscordIntegrationModule.SwitchToMainMenu();
 
+            _screenExitStatus.Set();
+
             Application.Invoke(delegate
             {
                 _stopEmulation.Sensitive            = false;
@@ -432,12 +438,17 @@ namespace Ryujinx.Ui
             if (device != null)
             {
                 UpdateGameMetadata(device.System.TitleIdText);
+
+                if (_screen != null)
+                {
+                    _screen.Exit();
+                    _screenExitStatus.WaitOne();
+                }
             }
 
             Dispose();
 
             Profile.FinishProfiling();
-            device?.Dispose();
             DiscordIntegrationModule.Exit();
             Logger.Shutdown();
             Application.Quit();
@@ -584,13 +595,11 @@ namespace Ryujinx.Ui
 
         private void Exit_Pressed(object sender, EventArgs args)
         {
-            _screen?.Exit();
             End(_emulationContext);
         }
 
         private void Window_Close(object sender, DeleteEventArgs args)
         {
-            _screen?.Exit();
             End(_emulationContext);
         }