/// <summary> /// Following standard framework guideline dispose pattern /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources..</param> protected virtual void Dispose(bool disposing) { if (disposing) { ThreadingService.JoinableTaskFactory.Run(async delegate { #pragma warning disable CA2007 // Do not directly await a Task (see https://github.com/dotnet/roslyn/issues/6770) await LanguageServiceRegister.UnregisterAsync(this); #pragma warning restore CA2007 // Do not directly await a Task if (_intellisenseEngine != null) { await ThreadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); Marshal.ThrowExceptionForHR(_intellisenseEngine.StopIntellisenseEngine()); Marshal.ThrowExceptionForHR(_intellisenseEngine.Close()); _intellisenseEngine = null; } _designTimeBuildSubscriptionLink?.Dispose(); _evaluationSubscriptionLink?.Dispose(); }); } }
/// <inheritdoc/> async Task IProjectWithIntellisense.OnProjectRemovedAsync(UnconfiguredProject unconfiguredProject, IVsIntellisenseProject intellisenseProject) { ProjectReferenceState state; if (_projectReferenceFullPaths.TryGetValue(unconfiguredProject.FullPath, out state)) { await ThreadingService.JoinableTaskFactory.SwitchToMainThreadAsync(); Marshal.ThrowExceptionForHR(_intellisenseEngine.RemoveP2PReference(intellisenseProject)); state.AsProjectReference = false; if (state.ResolvedPath != null) { Marshal.ThrowExceptionForHR(_intellisenseEngine.AddAssemblyReference(state.ResolvedPath)); } Marshal.ThrowExceptionForHR(_intellisenseEngine.StartIntellisenseEngine()); } }
/// <summary> /// Invoked when the UnconfiguredProject is first loaded to initialize language services. /// </summary> protected async Task InitializeAsync() { ProjectAsynchronousTasksService.UnloadCancellationToken.ThrowIfCancellationRequested(); // Don't start until the project has been loaded as far as the IDE is concerned. #pragma warning disable CA2007 // Do not directly await a Task (see https://github.com/dotnet/roslyn/issues/6770) await ProjectAsyncLoadDashboard.ProjectLoadedInHost; #pragma warning restore CA2007 // Do not directly await a Task // Defer this work until VS has idle time. Otherwise we'll block the UI thread to load the MSBuild project evaluation // during synchronous project load time. await ThreadHelper.JoinableTaskFactory.RunAsync( VsTaskRunContext.UIThreadBackgroundPriority, async delegate { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); await Task.Yield(); using (ProjectAsynchronousTasksService.LoadedProject()) { // hack to ensure webproj package is properly sited, by forcing it to load with a QueryService call for // one of the services it implements. var tmpObj = Package.GetGlobalService(typeof(SWebApplicationCtxSvc)) as IWebApplicationCtxSvc; Report.IfNotPresent(tmpObj); if (tmpObj == null) { return; } // Create the Intellisense engine for C# var registry = ServiceProvider.GetService(typeof(SLocalRegistry)) as ILocalRegistry3; Assumes.Present(registry); IntPtr pIntellisenseEngine = IntPtr.Zero; try { Marshal.ThrowExceptionForHR(registry.CreateInstance( IntelliSenseProviderGuid, null, typeof(IVsIntellisenseProject).GUID, (uint)CLSCTX.CLSCTX_INPROC_SERVER, out pIntellisenseEngine)); _intellisenseEngine = Marshal.GetObjectForIUnknown(pIntellisenseEngine) as IVsIntellisenseProject; } finally { if (pIntellisenseEngine != IntPtr.Zero) { Marshal.Release(pIntellisenseEngine); } } Marshal.ThrowExceptionForHR(_intellisenseEngine.Init(this)); #pragma warning disable CA2007 // Do not directly await a Task (see https://github.com/dotnet/roslyn/issues/6770) await LanguageServiceRegister.RegisterProjectAsync(this); #pragma warning restore CA2007 // Do not directly await a Task } }); // The rest of this can execute on a worker thread. await TaskScheduler.Default; using (ProjectAsynchronousTasksService.LoadedProject()) { var designTimeBuildBlock = new ActionBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> >( ProjectBuildRuleBlock_ChangedAsync); _designTimeBuildSubscriptionLink = ActiveConfiguredProjectSubscriptionService.JointRuleSource.SourceBlock.LinkTo( designTimeBuildBlock, ruleNames: WatchedEvaluationRules.Union(WatchedDesignTimeBuildRules)); var evaluationBlock = new ActionBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> >( ProjectRuleBlock_ChangedAsync); _evaluationSubscriptionLink = ActiveConfiguredProjectSubscriptionService.JointRuleSource.SourceBlock.LinkTo( evaluationBlock, ruleNames: WatchedEvaluationRules); } }