From 7cb14bbf563c574112de9d35a4054a28cc158751 Mon Sep 17 00:00:00 2001 From: Matt Ward Date: Thu, 19 May 2011 21:34:09 +0100 Subject: [PATCH] Fix hang caused by Package Management console on closing SharpDevelop with a solution open. --- .../IPackageManagementConsoleHost.cs | 1 + .../Scripting/PackageManagementConsoleHost.cs | 11 ++++++--- .../Scripting/PackageManagementConsolePad.cs | 24 +++++++++++++++++++ .../PackageManagementConsoleViewModel.cs | 5 ++++ .../FakePackageManagementConsoleHost.cs | 7 ++++++ .../PackageManagementConsoleHostTests.cs | 20 ++++++++++++++++ .../PackageManagementConsoleViewModelTests.cs | 10 ++++++++ 7 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/IPackageManagementConsoleHost.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/IPackageManagementConsoleHost.cs index d69481ed97..53ab197ed7 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/IPackageManagementConsoleHost.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/IPackageManagementConsoleHost.cs @@ -21,6 +21,7 @@ namespace ICSharpCode.PackageManagement.Scripting void Clear(); void WritePrompt(); void Run(); + void ShutdownConsole(); IPackageManagementProject GetProject(string packageSource, string projectName); IPackageManagementProject GetProject(IPackageRepository sourceRepository, string projectName); diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleHost.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleHost.cs index a6a90abd30..b9b29d74d1 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleHost.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleHost.cs @@ -58,9 +58,7 @@ namespace ICSharpCode.PackageManagement.Scripting public void Dispose() { - if (ScriptingConsole != null) { - ScriptingConsole.Dispose(); - } + ShutdownConsole(); if (thread != null) { thread.Join(); @@ -228,5 +226,12 @@ namespace ICSharpCode.PackageManagement.Scripting projectName = GetActiveProjectName(projectName); return Solution.GetProject(sourceRepository, projectName); } + + public void ShutdownConsole() + { + if (ScriptingConsole != null) { + ScriptingConsole.Dispose(); + } + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsolePad.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsolePad.cs index 209e74a2ed..f6b9fcd3cc 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsolePad.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsolePad.cs @@ -2,6 +2,7 @@ // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using System; +using System.Windows.Threading; using ICSharpCode.SharpDevelop.Gui; namespace ICSharpCode.PackageManagement.Scripting @@ -24,9 +25,32 @@ namespace ICSharpCode.PackageManagement.Scripting public override void Dispose() { if (viewModel != null) { + viewModel.ShutdownConsole(); + DoEvents(); viewModel.Dispose(); viewModel = null; } } + + /// + /// Allow package management console thread to finish. Can be busy if solution was open when the user + /// closed SharpDevelop. + /// + void DoEvents() + { + DispatcherFrame frame = new DispatcherFrame(); + Dispatcher.CurrentDispatcher.BeginInvoke( + DispatcherPriority.Background, + new DispatcherOperationCallback(ExitFrame), + frame); + Dispatcher.PushFrame(frame); + } + + object ExitFrame(object frame) + { + var dispatcherFrame = frame as DispatcherFrame; + dispatcherFrame.Continue = false; + return null; + } } } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleViewModel.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleViewModel.cs index 39a9f7b62f..f055f28589 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleViewModel.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleViewModel.cs @@ -224,5 +224,10 @@ namespace ICSharpCode.PackageManagement.Scripting { consoleHost.Dispose(); } + + public void ShutdownConsole() + { + consoleHost.ShutdownConsole(); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageManagementConsoleHost.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageManagementConsoleHost.cs index b4e35e1e20..c04894f4aa 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageManagementConsoleHost.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakePackageManagementConsoleHost.cs @@ -96,5 +96,12 @@ namespace PackageManagement.Tests.Helpers } public bool IsRunning { get; set; } + + public bool IsShutdownConsoleCalled; + + public void ShutdownConsole() + { + IsShutdownConsoleCalled = true; + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleHostTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleHostTests.cs index e1b5a08c9d..6af899a77d 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleHostTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleHostTests.cs @@ -525,5 +525,25 @@ namespace PackageManagement.Tests.Scripting Assert.IsTrue(executed); } + + [Test] + public void ShutdownConsole_ScriptingConsoleCreated_DisposesScriptingConsole() + { + CreateHost(); + host.ShutdownConsole(); + + bool disposed = host.FakeScriptingConsole.IsDisposeCalled; + + Assert.IsTrue(disposed); + } + + [Test] + public void ShutdownConsole_ScriptingConsoleIsNull_NullReferenceExceptionIsNotThrown() + { + CreateHost(); + host.ScriptingConsole = null; + + Assert.DoesNotThrow(() => host.ShutdownConsole()); + } } } diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleViewModelTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleViewModelTests.cs index 67a77e5b4d..012acc75de 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleViewModelTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleViewModelTests.cs @@ -500,5 +500,15 @@ namespace PackageManagement.Tests.Scripting Assert.IsTrue(consoleHost.IsRunCalled); } + + [Test] + public void ShutdownConsole_NewViewModelCreated_ScriptingConsoleIsShutdown() + { + CreateViewModel(); + viewModel.ShutdownConsole(); + + bool shutdownConsole = consoleHost.IsShutdownConsoleCalled; + Assert.IsTrue(shutdownConsole); + } } }