KB928365 for MS07-040 Leaves Some Managed Applications Sluggish

After installing Security Update KB928365 for the Microsoft .NET Framework 2.0 to fix MS07-040, some users are noticing some managed applications – especially those developed using the Windows Presentation Framework (WPF) – are running sluggish.

The apparent problem is that native images, which are assemblies already compiled to native code, do not exist for all assemblies but a few. Those assemblies for which native images do not exist, like PresentationCore.dll for WPF, must be just-in-time compiled, or JIT’d, when code must be executed each time the assembly is loaded until they compiled to native code (NGEN’d) while the machine is idle.

To work around this issue,

  1. Open a console.
    1. On Windows Vista and newer, click on the Start button and type “cmd.exe” (without quotes). When found, right-click on the item and select “Run as administrator”.
    2. On Windows 2000, XP, and 2003, click on the Start button, click Run, type “cmd.exe” (without quotes) and click OK.
  2. Type the following and press Enter.

    %WINDIR%Microsoft.NETFrameworkv2.0.50727ngen.exe executeQueuedItems

This will take some time but applications will run more quickly again since assemblies will not have to be JIT’d.

The root problem is that the patch only targets a single Windows Installer package, or MSI, and the Microsoft .NET Framework 3.0 redistributable is actually composed of multiple MSIs including the .NET Framework 2.0 MSI. Inside of some of these MSIs is a custom action that queues assemblies the MSI installs to be compiled to native images, or NGEN’d, at different priorities. Priority 1 assemblies are NGEN’d immediately at the end of each MSI installation. All other assemblies to be NGEN’d that are not explicitly queued are given the default priority of 3 and will, by default, be NGEN’d when the machine is idle.

When you initially installed the Microsoft .NET Framework 3.0 redistributable, all MSIs were installed and so the custom actions in each MSI were run. Some assemblies like mscorlib.dll and System.dll in the .NET Framework 2.0 MSI were queued as priority 1 while others were queued as priority 3. Some assemblies like PresentationCore.dll in the WPF MSI were queued as priority 1 as well. But when a patch is installed, only installed products that the patch targets are reinstalled. In the case of KB928365 only the .NET Framework 2.0 MSI is reinstalled so only its custom actions are executed to re-queue some of its assemblies at priority 1. All other assemblies dependent on any updates are queued at the default priority of 3.

Toward the end of the patch installation, priority 1 assemblies are NGEN’d immediate but priority 3 assemblies will only be NGEN’d when the machine is idle. For those curious, priority 2 assemblies are aggressively compiled after priority 1 assemblies.