зеркало из https://github.com/mono/nuget.git
Invoke the restore wait dialog on the UI thread
This commit is contained in:
Родитель
89abb5f2a3
Коммит
ef404b5159
|
@ -8,6 +8,9 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
using EnvDTE;
|
||||
using Microsoft.VisualStudio.Project;
|
||||
using Microsoft.VisualStudio.Project.Designers;
|
||||
|
@ -133,15 +136,17 @@ namespace NuGet.VisualStudio
|
|||
_waitDialogFactory.CreateInstance(out waitDialog);
|
||||
try
|
||||
{
|
||||
waitDialog.StartWaitDialog(
|
||||
VsResources.DialogTitle,
|
||||
VsResources.PackageRestoreWaitMessage,
|
||||
String.Empty,
|
||||
varStatusBmpAnim: null,
|
||||
szStatusBarText: null,
|
||||
iDelayToShowDialog: 0,
|
||||
fIsCancelable: false,
|
||||
fShowMarqueeProgress: true);
|
||||
// Start the wait dialog on the UI thread
|
||||
InvokeOnUIThread(() =>
|
||||
waitDialog.StartWaitDialog(
|
||||
VsResources.DialogTitle,
|
||||
VsResources.PackageRestoreWaitMessage,
|
||||
String.Empty,
|
||||
varStatusBmpAnim: null,
|
||||
szStatusBarText: null,
|
||||
iDelayToShowDialog: 0,
|
||||
fIsCancelable: false,
|
||||
fShowMarqueeProgress: true));
|
||||
|
||||
if (fromActivation)
|
||||
{
|
||||
|
@ -159,7 +164,8 @@ namespace NuGet.VisualStudio
|
|||
finally
|
||||
{
|
||||
int canceled;
|
||||
waitDialog.EndWaitDialog(out canceled);
|
||||
|
||||
InvokeOnUIThread(() => waitDialog.EndWaitDialog(out canceled));
|
||||
}
|
||||
|
||||
if (fromActivation)
|
||||
|
@ -283,7 +289,7 @@ namespace NuGet.VisualStudio
|
|||
return;
|
||||
}
|
||||
|
||||
if (!VsVersionHelper.IsVisualStudio2010 &&
|
||||
if (!VsVersionHelper.IsVisualStudio2010 &&
|
||||
(project.IsJavaScriptProject() || project.IsNativeProject()))
|
||||
{
|
||||
if (VsVersionHelper.IsVisualStudio2012)
|
||||
|
@ -350,7 +356,7 @@ namespace NuGet.VisualStudio
|
|||
buildProject.FullPath,
|
||||
PathUtility.EnsureTrailingSlash(_solutionManager.SolutionDirectory));
|
||||
relativeSolutionPath = PathUtility.EnsureTrailingSlash(relativeSolutionPath);
|
||||
|
||||
|
||||
var solutionDirProperty = buildProject.Xml.AddProperty(solutiondir, relativeSolutionPath);
|
||||
solutionDirProperty.Condition =
|
||||
String.Format(
|
||||
|
@ -381,7 +387,7 @@ namespace NuGet.VisualStudio
|
|||
{
|
||||
// download NuGet.Build and NuGet.CommandLine packages into the .nuget folder,
|
||||
// using the active package source first and fall back to other enabled package sources.
|
||||
IPackageRepository repository = CreatePackageRestoreRepository();
|
||||
IPackageRepository repository = CreatePackageRestoreRepository();
|
||||
|
||||
var installPackages = new string[] { NuGetBuildPackageName, NuGetCommandLinePackageName };
|
||||
foreach (var packageId in installPackages)
|
||||
|
@ -608,5 +614,20 @@ namespace NuGet.VisualStudio
|
|||
|
||||
return new PackageReference[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the action on the UI thread if one exists.
|
||||
/// </summary>
|
||||
private void InvokeOnUIThread(Action action)
|
||||
{
|
||||
if (Application.Current != null)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(action);
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,14 +20,22 @@ namespace NuGet.VisualStudio12
|
|||
#if VS12
|
||||
|
||||
/// <summary>
|
||||
/// Performs an action inside a VS internal writer lock. This method runs synchronously but uses several different
|
||||
/// threads to avoid deadlocks with the project system.
|
||||
/// Performs an action inside a VS internal writer lock. If called from the UI thread this method will
|
||||
/// run async to avoid deadlocks.
|
||||
/// </summary>
|
||||
public static void DoWorkInWriterLock(Project project, IVsHierarchy hierarchy, Action<MsBuildProject> action)
|
||||
{
|
||||
// peform this work on a new thread to avoid moving our current thread
|
||||
// Perform this work on a new thread to avoid moving our current thread, and so it can be done async if needed.
|
||||
var task = Task.Run(() => DoWorkInWriterLockInternal(project, hierarchy, action));
|
||||
task.Wait();
|
||||
|
||||
// Check if we are running on the UI thread. If we are we cannot risk blocking and holding the lock.
|
||||
// Ideally all calls involving the lock should be done on a background thread from the start to
|
||||
// keep the call as synchronous as possible within NuGet.
|
||||
if (!Microsoft.VisualStudio.Shell.ThreadHelper.CheckAccess())
|
||||
{
|
||||
// If we are on a background thread we can safely run synchronously.
|
||||
task.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task DoWorkInWriterLockInternal(Project project, IVsHierarchy hierarchy, Action<MsBuildProject> action)
|
||||
|
|
|
@ -209,7 +209,17 @@ namespace NuGet.Tools
|
|||
// the <Import> element added.
|
||||
if (PackageRestoreManager.IsCurrentSolutionEnabledForRestore)
|
||||
{
|
||||
PackageRestoreManager.EnableCurrentSolutionForRestore(fromActivation: false);
|
||||
if (VsVersionHelper.IsVisualStudio2013)
|
||||
{
|
||||
// Run on a background thread in VS2013 to avoid CPS hangs. The modal loading dialog will block
|
||||
// until this completes.
|
||||
ThreadPool.QueueUserWorkItem(new WaitCallback((obj) =>
|
||||
PackageRestoreManager.EnableCurrentSolutionForRestore(fromActivation: false)));
|
||||
}
|
||||
else
|
||||
{
|
||||
PackageRestoreManager.EnableCurrentSolutionForRestore(fromActivation: false);
|
||||
}
|
||||
}
|
||||
|
||||
// when NuGet loads, if the current solution has some package
|
||||
|
|
|
@ -63,7 +63,7 @@ function Test-EnablePackageRestoreModifyProjectThatInstallNewPackages
|
|||
Assert-AreEqual "true" (Get-MsBuildPropertyValue $p "RestorePackages")
|
||||
}
|
||||
|
||||
function Test-EnablePackageRestoreOnCpsProjects
|
||||
function NoTest-EnablePackageRestoreOnCpsProjects
|
||||
{
|
||||
if ($dte.Version -eq "10.0")
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче