管理解决方案中的项目加载

Visual Studio 解决方案可以包含大量项目。 默认的 Visual Studio 行为是在打开解决方案时加载解决方案中的所有项目,在完成加载之前,不允许用户访问任何项目。 当项目加载过程持续两个多分钟时,将显示一个进度栏,其中显示了已加载的项目数和项目总数。 用户在处理具有多个项目的解决方案时可以卸载项目,但此过程有一些缺点:未将卸载的项目作为重新生成解决方案命令的一部分生成,并且不显示关闭项目的类型和成员的 IntelliSense 说明。

开发人员可以通过创建解决方案加载管理器来减少解决方案加载时间并管理项目加载行为。 解决方案加载管理器可以确保在启动后台生成之前加载项目,延迟后台加载,直到其他后台任务完成,并执行其他项目负载管理任务。

创建解决方案加载管理器

开发人员可以通过实现 IVsSolutionLoadManager 并建议 Visual Studio 解决方案加载管理器处于活动状态来创建解决方案加载管理器。

激活解决方案加载管理器

Visual Studio 在给定时间只允许一个解决方案加载管理器,因此在想要激活解决方案加载管理器时,必须向 Visual Studio 提供建议。 如果稍后激活第二个解决方案加载管理器,解决方案加载管理器将断开连接。

必须获取该服务 SVsSolution 并设置 __VSPROPID4。 VSPROPID_ActiveSolutionLoadManager属性:

IVsSolution pSolution = GetService(typeof(SVsSolution)) as IVsSolution;
object objLoadMgr = this;   //the class that implements IVsSolutionManager
pSolution.SetProperty((int)__VSPROPID4.VSPROPID_ActiveSolutionLoadManager, objLoadMgr);

OnDisconnect当 Visual Studio 正在关闭或通过调用 __VSPROPID4 来接管其他包作为活动解决方案加载管理器时,将调用SetProperty此方法。 VSPROPID_ActiveSolutionLoadManager属性。

不同类型的解决方案加载管理器的策略

可以通过不同的方式实现解决方案加载管理器,具体取决于它们要管理的解决方案类型。

如果解决方案加载管理器旨在一般管理解决方案加载,则可以将其作为 VSPackage 的一部分实现。 应通过将 ProvideAutoLoadAttribute VSPackage 添加到值为 <a0/a0> 的 VSPackage,将包设置为自动加载。 然后,可以在方法中 Initialize 激活解决方案加载管理器。

注意

有关自动加载包的详细信息,请参阅加载 VSPackage。

由于 Visual Studio 仅识别要激活的最后一个解决方案加载管理器,因此常规解决方案加载管理器应始终检测是否存在现有负载管理器,然后再激活自己。 如果为 __VSPROPID4 调用 GetProperty() 解决方案服务 VSPROPID_ActiveSolutionLoadManager返回 null时,没有活动的解决方案加载管理器。 如果未返回 null,检查对象是否与解决方案加载管理器相同。

如果解决方案加载管理器只管理少数类型的解决方案,VSPackage 可以订阅解决方案加载事件(通过调用 AdviseSolutionEvents),并使用事件处理程序激活 OnBeforeOpenSolution 解决方案加载管理器。

如果解决方案加载管理器仅用于管理特定解决方案,则可以通过调用 WriteSolutionProps 解决方案前部分来保留激活信息作为解决方案文件的一部分。

特定的解决方案加载管理器应在事件处理程序中 OnAfterCloseSolution 停用自己,以免与其他解决方案加载管理器冲突。

如果需要解决方案加载管理器仅保留全局项目加载属性(例如,在“选项”页上设置的属性),则可以在 OnAfterOpenProject 事件处理程序中激活解决方案加载管理器,在解决方案属性中保留该设置,然后停用解决方案加载管理器。

处理解决方案加载事件

若要订阅解决方案加载事件,请在激活解决方案加载管理器时调用 AdviseSolutionEvents 。 如果实现 IVsSolutionLoadEvents,则可以响应与不同项目加载属性相关的事件。

  • OnBeforeOpenSolution:在打开解决方案之前会触发此事件。

  • OnBeforeBackgroundSolutionLoadBegins:此事件在解决方案完全加载后触发,但在后台项目加载重新开始之前。

  • OnAfterBackgroundSolutionLoadComplete:此事件在解决方案最初完全加载后触发,无论是否存在解决方案加载管理器。 每当解决方案完全加载时,也会在后台加载或需求加载后触发它。 同时重新 SolutionExistsAndFullyLoaded_guid 激活。

  • OnQueryBackgroundLoadProjectBatch:在加载项目(或项目)之前触发此事件。 若要确保在加载项目之前完成其他后台进程,请设置为 pfShouldDelayLoadToNextIdle true

  • OnBeforeLoadProjectBatch:一批项目即将加载时,将触发此事件。 如果fIsBackgroundIdleBatch为 true,则项目将在后台加载;如果fIsBackgroundIdleBatch为 false,则由于用户请求而同步加载项目,例如,如果用户在解决方案资源管理器中展开挂起的项目。 可以处理此事件以执行成本高昂的工作,否则需要在该操作中 OnAfterOpenProject完成。

  • OnAfterLoadProjectBatch:加载一批项目后,将触发此事件。

检测和管理解决方案和项目加载

若要检测项目和解决方案的加载状态,请使用以下值进行调用 GetProperty

  • __VSPROPID4。VSPROPID_IsSolutionFullyLoadedvar 如果加载解决方案及其所有项目,则返回 true ;否则 false返回。

  • __VSPROPID4。VSPROPID_IsInBackgroundIdleLoadProjectBatch: var 如果当前正在后台加载一批项目,则返回 true ;否则 false返回。

  • __VSPROPID4。VSPROPID_IsInSyncDemandLoadProjectBatch:var如果由于用户命令或其他显式加载,当前正在同步加载一批项目,则false返回true

  • __VSPROPID2。VSPROPID_IsSolutionClosing: var 如果解决方案当前处于关闭状态,则返回 true ;否则 false返回。

  • __VSPROPID。VSPROPID_IsSolutionOpening: var 如果当前打开解决方案,则返回 true ;否则 false返回。

还可以通过调用以下方法之一来确保项目和解决方案已加载: