2

If I create a new WinForms project targeting .NET Framework 4.7.2, and replace Program with the following code

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        foo();
    }

    static void foo()
    {
        MessageBox.Show("a");
    }
}

When I set a breakpoint on the call to foo and then step in, there is a delay of over 300ms in entering the function. The delay is caused by the JIT attempting to load System.Windows.Forms.dll.

Investigating with Process Monitor, I've observed that over 300ms is spent making multiple attempts to load a file C:\Windows\assembly\pubpol636.dat that doesn't exist

10:51:16.8555650 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:16.8556539 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:16.8970666 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:16.8971453 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:16.9285253 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:16.9286231 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:16.9606527 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:16.9607522 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:16.9938988 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:16.9940084 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:17.0387184 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:17.0389674 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:17.0691301 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:17.0692622 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:17.1004577 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:17.1005328 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:17.1319618 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:17.1324102 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND
10:51:17.1635977 PM WindowsFormsApp1.exe    48888   RegQueryValue   HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Latest   SUCCESS
10:51:17.1636861 PM WindowsFormsApp1.exe    48888   CreateFile  C:\Windows\assembly\pubpol636.dat   NAME NOT FOUND

The stack trace of these calls is as follows

KernelBase!CreateFileW + 0x6d
clr!CPublisherPolicy::LoadBitmaskData + 0xbd
clr!CPublisherPolicy::Init + 0x1d3
clr!CPublisherPolicy::Create + 0x52
clr!CAppCtxPolicyConfigs::Create + 0x34
clr!CAsmDownloadMgr::PreDownloadCheck + 0x186
clr!CAssemblyDownload::PreDownload + 0x108
clr!CAssemblyName::BindToObject + 0x121f
clr!FusionBind::RemoteLoad + 0x269
clr!AssemblySpec::LoadAssembly + 0x244
clr!AssemblySpec::FindAssemblyFile + 0xf1
clr!AppDomain::BindAssemblySpec + 0x1296
clr!PEFile::LoadAssembly + 0xc3
clr!Module::LoadAssembly + 0x14c
clr!Assembly::FindModuleByTypeRef + 0x248
clr!ClassLoader::LoadTypeDefOrRefThrowing + 0x115
clr!MemberLoader::GetDescFromMemberRef + 0x2e8
clr!CEEInfo::resolveToken + 0x351
clr!Compiler::impResolveToken + 0x48
...

The source of clr!CPublisherPolicy::LoadBitmaskData does not appear to be available on GitHub, however decompiling this function with IDA Pro, I can see that it makes 10 attempts to load a pubpol policy file, waiting 30ms between each attempt! .NET Core does not have this problem, however I am multi-targeting both .NET Framework and .NET Core, and I just can't believe that the CLR has a forced 300ms delay that occurs when trying to load an assembly.

I tried to put a publisher policy in my App.config file, however this did not seem to prevent this 300ms delay. This could theoretically affect any DLL, however in practice it does not. I haven't figured out what's special about System.Windows.Forms.dll yet that triggers the code path that leads to the 300ms delay, when other DLLs clearly don't have this issue. I haven't found any evidence of anyone else ever having noticed this issue, which makes me seriously question whether I'm somehow doing something wrong - surely someone would have noticed such a big delay before!

--

Further testing seems to show that every .NET Framework application on my computer is wasting 300ms at startup looking for a C:\Windows\assembly\pubpolXXX.dat file. The issue is not specific to WinForms. Creating an empty file with the name it's after "fixes" the issue, but this isn't really a proper solution. The issue also does not occur if you do not have the "Latest" item under HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default

4
  • 1
    That's quite mysterious. No idea why it might be happening, but since publisher policies have to do with assembly forwarding and you are working with .NET Framework, maybe try enabling CLR activation debugging and see if something jumps out at you. (Or if debugging was previously enabled, try disabling it.) Commented May 24 at 14:06
  • 1
    This might be relevant: Slow wpf startup due to publish policy... maybe. Commented May 24 at 14:10
  • 1
    What is the value of HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default on your machine by the way? On mine, it's 0x5c and I don't seem to have this problem. (I have no idea what that means though.) Commented May 24 at 14:48
  • On my machine, running Windows 11, I have several values under HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default\Default: index636, Latest, LegacyPolicyTimeStamp, Oldest and UsageMask. The value of Latest (a REG_DWORD) is 636 (hence why it's looking for pubpol636.dat). However, I checked a server running Server 2022 and it didn't have any values under HKLM\SOFTWARE\Microsoft\Fusion\PublisherPolicy\Default. My computer has .NET 533320 (4.8.1 or later) while the Server 2022 system has 528449 (4.8) Commented May 24 at 15:48

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.