Как JIT-компилятор решает, когда инициализировать статические конструкторы - PullRequest
0 голосов
/ 17 декабря 2009

Недавно я наблюдал следующий интересный сценарий в одном из приложений, которые я разрабатываю с использованием .NET 3.5. В этом конкретном приложении у меня есть объект-одиночка, к которому я обращаюсь как статическая переменная. Я ожидал, что среда выполнения .NET должна инициализировать этот одноэлементный объект при первом обращении к нему, но, похоже, это не так. Среда выполнения .NET инициализирует его прежде, чем я получу доступ к этому объекту. Ниже приведен некоторый код peudo,

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

Даже во время выполнения мой код выполняет код только в стороне, если оператор .NET runtime все еще инициализирует объект singleton. В некоторых приложениях мне вообще не нужен доступ к этому объекту 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 ]

3 голосов
/ 17 декабря 2009

Предлагаю вам прочитать статью Джона Скита о шаблоне Singleton в C # и его приложение о отложенной загрузке и т. Д. Вы получите лучшее понимание вопросов реализации.

2 голосов
/ 17 декабря 2009

С Спецификация языка C # :

Статический конструктор для класса выполняется не более одного раза в данной области приложения. Выполнение статического конструктора инициируется первым из следующих событий, происходящих в домене приложения:

  • Экземпляр класса создан.
  • Ссылка на любой статический член класса.
...