Async loaded .NET projects may impact Visual Studio extensions

Mads Kristensen

In Visual Studio 2019 version 16.3, the CSProj project system (C#/VB non-SDK style) introduces a new way of loading called Partial Load Mode (PLM). After the solution loads, the project system is doing design time builds in the background, leaving the UI responsive and interactive. However, for the time it takes to run the design time build, certain features may not be working as they used to. Extenders, read on.

Today, CSProj projects block the UI thread and wait for design time build and Roslyn initialization before firing the project load event. To further reduce solution load time, CSProj will now fire the project load event immediately after evaluation, since that is early enough to display the project tree in Solution Explorer and provide project and source code files to Roslyn.

Design time builds will happen on a background thread. This means that IntelliSense, code navigation, and designers will be in the Partial Load Mode after solution load and until the design time build results are ready. Most users will not even notice this happening beyond faster loading solutions.

This will match the current behavior of .NET SDK-style projects that has had this capability since Visual Studio 2017. Now the experience is consistent between CSProj and SDK-style projects.

Breaking change

Calls to Roslyn APIs, such as Workspace.CurrentSolution or ProjectItem.FileCodeModel, may return an incomplete code model in PLM because project references are not yet known to Roslyn. You may have to update your extension if it’s calling on the Roslyn API shortly after solution load.

Here’s how:

var operationProgressStatusService = await this.GetServiceAsync(typeof(SVsOperationProgressStatusService)) as IVsOperationProgressStatusService;
var stageStatus = operationProgressStatusService.GetStageStatus(CommonOperationProgressStageIds.Intellisense);

await stageStatus.WaitForCompletionAsync();

Learn more in the OperationProgress sample.

Editor owners should make an explicit decision regarding delaying the initialization of documents when IntelliSense is in progress.

To opt-out of deferring document creation, set the following in the .pkgdef file:

[$RootKey$\Editors\<Editor-type-Guid>]
"DeferUntilIntellisenseIsReady"=dword:00000000

To opt into deferring document creation (this is the current default behavior to avoid breaking compatibility with extensions depending on Roslyn data), set the following in the .pkgdef file:

[$RootKey$\Editors\<Editor-type-Guid>]
"DeferUntilIntellisenseIsReady"=dword:00000001

Test your extension

This change brings a feature currently used by SDK-style projects to the CSProj based ones. As such, it is unlikely going to cause issues for most extensions unless they have different code paths for each of the two project systems. We therefore regard this as low impact for the extension ecosystem, but it could have a big impact on an individual extension.

To find out if this change affected your extensions, download Visual Studio 2019 v16.3 Preview 1 today.

Then drop a .json file containing the below code into %LocalAppData%\Microsoft\VisualStudio\RemoteSettings\LocalTest\PersistentActions

{
  "ActionPath": "vs\\core\\remotesettings",
  "ActionJson": {
    "FeatureFlags": {
      "CPS.UseOperationProgress": 0,
      "CSProj.PartialLoadMode": 1,
      "Designer.PartialLoadMode": 1,
      "Completion.PartialLoadMode": 1,
      "Roslyn.PartialLoadMode": 1
      }
  },

  "TriggerJson": null,
  "MaxWaitTimeSpan": "14.00:00:00",
  "Categories": [
  ]
}

Then restart Visual Studio twice. Yes, twice. This will enable PLM for CSProj based projects.

To revert the feature flags change – delete the .json file and restart Visual Studio twice. Disabling PLM is only an option in the initial preview of Visual Studio 2019 v16.3. The option will be removed in a future update.

13 comments

Discussion is closed. Login to edit/delete existing comments.

  • Chuck Ryan 0

    You guys have really gone all in on the whole ‘no options’ idea. How do we tell when this PLM mode is finished so we can actually get some work done without all the delays and instability it will cause? I would much prefer to wait a couple of minutes for the system to fully load the solution rather than wait 10 minutes for it to stop pretending it loaded.

    • Viktor VeisMicrosoft employee 0

      Thank you for your feedback. The intent is to unblock Visual Studio early, so developers can navigate to a file and read code while IntelliSense is being initialized on the background. Or you can wait for the ‘Loading IntelliSense’ progress bar to complete. There is a screenshot in the blog. Time to initialize IntelliSense doesn’t change much. We just don’t block solution load for it anymore.

      • Chuck Ryan 0

        Thanks, the startup process is just getting so rediculously complex as the theme seems to be more to make it seem like things are loading faster while actually you still have to wait at least as long, if not longer due to it being turned into a background process, and I have seen too many errors and crashes since this all started. I do not mind waiting on a large solution to load as long as it loads correctly since having to do it again when it crashes does not end up saving me time. The whole load optimization messages are particularly funny as I have had Visual Studio tell me several times that I could save startup time by stopping the SSRS module from loading when openeing an SSRS project.

        • Viktor VeisMicrosoft employee 0

          If you haven’t already, could you please report your crashes and hangs to http://aka.ms/vs-rap? This will provide us with diagnostic information to investigate. Thank you!

          • Chuck Ryan 0

            Sorry, I have stopped gethering/reporting information about the various issues I am having with Visual Studio. I have finally admitted to myself that the old hypothesis about doing the same thing over and over again, while expecting different results, is now proven fact.

        • Alex Postlethwaite 0

          I agree.
          The timespan from VS open -> “VS ready” might have gotten shorter, but it’s not actually ready to do anything. It’s still got a whole load of background processing to go on before you can really do anything.
          VS open -> VS usable used to be slower but at least predictable.
          In my opinion, you’ve only improved startup times by changing and moving the goalposts.

          • Varun GuptaMicrosoft employee 0

            Hi Alex, I would like to understand this better. Is it OK if I reach out to you? or you can just email me at vssolutionload at microsoft dot com?

            Thanks!

        • Varun GuptaMicrosoft employee 0

          Hi Chuck, I would like to understand this better. Is it OK if I reach out to you? or you can just email me at vssolutionload at microsoft dot com?

          Thanks!

        • Varun GuptaMicrosoft employee 0

          Hi Chuck,

          Thank you for taking time to write your feedback. I would like to understand your feedback in more detail and develop an understanding for your perspective about this feature.

          Is it OK if I reach out to you? or you can just email me at vssolutionload at microsoft dot com?

          Thank you in advance for your time, I look forward to hearing from you.

          Thank you!

  • bokij 0

    Very detailed thank you.

  • A Hosch 0

    Any details on why the restart twice?

  • dalmat501 _ 0

    best way of avoid this kind of problem is deleting Roslyn of the current project. You must eliminate the obj and bin folders and reinstall the application

Feedback usabilla icon