JIT编译器如何决定何时初始化静态构造函数

时间:2009-12-17 14:24:21

标签: c# .net static jit

最近,我在使用.NET 3.5开发的应用程序之一中观察到了以下有趣的场景。在这个特定的应用程序中,我有一个singletion对象,我作为静态变量访问。我认为.NET运行时应该在我第一次访问它时初始化这个单例对象,但似乎并非如此。 .NET运行时在我访问此particalr对象之前初始化它。以下是一些peudo代码,

if(!initSingleton)
   //Do some work without using the singletion class.
else
   //Do some work using the singletion class.

即使在运行时,我的代码也只执行if语句中的代码.NET运行时仍然初始化单例对象。在某些应用程序运行中,我根本不需要访问这个pariticualr对象!

此外,我没有看到调试版本的这种行为。似乎这与优化的构建(发布版本)有关。

这是.NET运行时的预期行为吗?

更新

以下是实际代码,

private void InitServiceClient(NetworkCredential credentials, bool https)
        {
            string uri = currentCrawlingWebUrl;
            if (!uri.EndsWith("/"))
                uri = string.Concat(uri, "/");
            uri = string.Concat(uri, siteDataEndPointSuffix);

            siteDataService = new SiteData.SiteDataSoapClient();
            siteDataService.Endpoint.Address = new EndpointAddress(uri);

            if (credentials != null)
            {
                siteDataService.ClientCredentials.Windows.ClientCredential = credentials;
            }
            else if (MOSSStateHandler.Instance.UserName.Length > 0 && MOSSStateHandler.Instance.Password.Length > 0)
            {
                siteDataService.ClientCredentials.Windows.ClientCredential.UserName = MOSSStateHandler.Instance.UserName;
                siteDataService.ClientCredentials.Windows.ClientCredential.Password = MOSSStateHandler.Instance.Password;
                siteDataService.ClientCredentials.Windows.ClientCredential.Domain = MOSSStateHandler.Instance.Domain;
            }

            BasicHttpBinding httpBinding = (BasicHttpBinding)siteDataService.Endpoint.Binding;
            httpBinding.Security.Mode = (https ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.TransportCredentialOnly);

            string authmode = MOSSConnectorConfiguration.Instance.Config.GetString(ConfigConstants.SHAREPOINT_AUTH_PROVIDER, "ntlm");
            if (authmode.Equals("ntlm", StringComparison.OrdinalIgnoreCase))
                httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
            else if (authmode.Equals("kerberos", StringComparison.OrdinalIgnoreCase))
                httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
            else
                throw new Exception(string.Format("Not supported"));
        }

即使我的应用程序没有执行其他方面的代码,如果阻止类MOSSStateHandler被初始化。

2 个答案:

答案 0 :(得分:3)

我建议您阅读Jon Skeet关于C#中Singleton模式的article,以及关于延迟加载等的its appendix。您将更好地了解实现问题。

答案 1 :(得分:2)

来自C# language spec

  

类的静态构造函数在给定的应用程序域中最多执行一次。静态构造函数的执行由应用程序域中发生的以下第一个事件触发:

     
      
  • 创建了一个类的实例。
  •   
  • 引用该类的任何静态成员。
  •