Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/VisualStudio/LanguageService/XSharpLanguagePackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public void GetIntellisenseSettings(bool load)
protected override async System.Threading.Tasks.Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
instance = this;
Logger.Initialize();
await Logger.InitializeAsync();
await base.InitializeAsync(cancellationToken, progress);
_txtManager = await GetServiceAsync(typeof(SVsTextManager)) as IVsTextManager4;
Assumes.Present(_txtManager);
Expand Down
9 changes: 7 additions & 2 deletions src/VisualStudio/ProjectPackage/XSharpProjectPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,14 @@ public XSharpProjectPackage() : base()
/// </summary>
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
// Give the codemodel a way to talk to the VS Shell
// Give the codemodel a way to talk to the VS Shell.
// Everything on this path is awaited and must stay that way: when a solution is opened
// while VS is starting, the shell loads this package synchronously from
// Solution.OpenAsync() -> CanOpenProject() and waits for it on the UI thread. Blocking
// here while waiting for that same UI thread deadlocks the IDE.
_shellEvents = new XSharpShellEvents();
XSharp.Support.Logger.Initialize();
await _shellEvents.InitializeAsync();
await XSharp.Support.Logger.InitializeAsync();
this.RegisterToolWindows();

await base.InitializeAsync(cancellationToken, progress);
Expand Down
54 changes: 22 additions & 32 deletions src/VisualStudio/ProjectPackage/XSharpShellEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,34 +28,22 @@ internal class XSharpShellEvents
bool isInitialized = false;
static XSharpShellEvents()
{
// Only read the environment here. Showing the warning is UI work and would block while
// waiting for the UI thread, which deadlocks when we are constructed during a package
// load that the shell is waiting for. It is reported from InitializeAsync() instead.
hasEnvironmentvariable = !string.IsNullOrEmpty(System.Environment.GetEnvironmentVariable("XSharpMsBuildDir"));
if (!hasEnvironmentvariable)
{
VS.MessageBox.ShowWarning("The environment variable 'XSharpMsBuildDir' is missing. \rSome projects may have problems loading. \rPlease run the XSharp setup program again.");
}
}

internal XSharpShellEvents()
{
if (ThreadHelper.CheckAccess())
{
// Already on UI thread
Initialize();
}
else
{
ThreadHelper.JoinableTaskFactory.Run(async delegate
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
Initialize();
});
}
}
internal void Initialize()
/// <summary>
/// Subscribe to the shell events. Must be awaited and never waited on: we are called from
/// XSharpProjectPackage.InitializeAsync(), where blocking while waiting for the UI thread
/// deadlocks the IDE. See the remarks on Logger.InitializeAsync().
/// </summary>
internal async Task InitializeAsync()
{
if (isInitialized)
return;
ThreadHelper.ThrowIfNotOnUIThread();
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
#if DEV17
VS.Events.SolutionEvents.OnAfterOpenSolution += SolutionEvents_OnAfterOpenSolution;
#endif
Expand All @@ -65,20 +53,22 @@ internal void Initialize()
VS.Events.SolutionEvents.OnBeforeOpenProject += SolutionEvents_OnBeforeOpenProject;

VS.Events.DocumentEvents.Closed += DocumentEvents_Closed;
ThreadHelper.JoinableTaskFactory.Run(async delegate
{

_ = await VS.Commands.InterceptAsync(KnownCommands.File_CloseSolution, CloseDesignerWindows);
_ = await VS.Commands.InterceptAsync(KnownCommands.File_Exit, CloseDesignerWindows);
var sol = await VS.Solutions.GetCurrentSolutionAsync();
_ = await VS.Commands.InterceptAsync(KnownCommands.File_CloseSolution, CloseDesignerWindows);
_ = await VS.Commands.InterceptAsync(KnownCommands.File_Exit, CloseDesignerWindows);
var sol = await VS.Solutions.GetCurrentSolutionAsync();
#if DEV17
if (sol is Solution)
{
SolutionEvents_OnAfterOpenSolution(sol);
}
if (sol is Solution)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
SolutionEvents_OnAfterOpenSolution(sol);
}
#endif
});
isInitialized = true;
if (!hasEnvironmentvariable)
{
VS.MessageBox.ShowWarningAsync("The environment variable 'XSharpMsBuildDir' is missing. \rSome projects may have problems loading. \rPlease run the XSharp setup program again.").FireAndForget();
}
}


Expand Down
Loading