Перенацеливание изменений для миграции на платформа .NET Framework 4.6.x

В этой статье перечислены проблемы совместимости приложений, представленные в платформа .NET Framework 4.6, 4.6.1 и 4.6.2.

.NET Framework 4.6

ASP.NET

HtmlTextWriter неправильно отображает элемент <br/>

Сведения

Начиная с .NET Framework 4.6, при вызове RenderBeginTag(String) и RenderEndTag() с элементом <BR /> правильно вставляется только один <BR /> (вместо двух).

Предложение

Если приложение зависит от дополнительного тега <BR />, RenderBeginTag(String) следует вызвать второй раз. Обратите внимание, что это изменение поведения влияет только на приложения, предназначенные для .NET Framework 4.6 или более поздних версий, поэтому другим вариантом является нацеливание на предыдущую версию платформы .NET Framework для получения старого поведения.

Имя. Значение
Область Microsoft Edge
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

ClickOnce

Приложения, опубликованные с помощью ClickOnce с использованием сертификата подписи кода SHA-256, могут завершиться ошибкой в Windows 2003

Сведения

Исполняемый файл подписывается с помощью SHA256. Ранее он подписывался с помощью SHA1 независимо от того, какой использовался сертификат подписи кода: SHA-1 или SHA-256. Применение:

  • Все приложения, собранные с помощью Visual Studio 2012 или более поздней версии.
  • Приложения, собранные с помощью Visual Studio 2010 или более ранней версии в системах с установленной платформой .NET Framework 4.5. Кроме того, при наличии .NET Framework 4.5 или более поздней версии манифест ClickOnce также подписывается с помощью SHA-256 для сертификатов SHA-256 независимо от версии .NET Framework, в которой проводилась компиляция.

Предложение

Изменение подписи исполняемого файла ClickOnce влияет только на системы Windows Server 2003; потребуется установка компонента из статьи базы знаний 938397 . Изменение подписи манифеста с SHA-256, даже если целевая платформа приложения — .NET Framework 4.0 или более ранней версии, вводит зависимость среды выполнения для .NET Framework 4.5 или более поздней версии.

Имя. Значение
Область Microsoft Edge
Версия 4,5
Тип Изменение целевой платформы

ClickOnce поддерживает SHA-256 в приложениях, предназначенных для версии 4.0

Сведения

Раньше приложению ClickOnce с сертификатом, подписанным с SHA-256, требовалась платформа .NET Framework 4.5 или более поздней версии, даже если приложение предназначено для версии 4.0. Теперь приложения ClickOnce, предназначенные для .NET Framework 4.0, можно запускать на .NET Framework 4.0, даже если они подписаны с помощью алгоритма SHA-256.

Предложение

Это изменение удаляет зависимость и позволяет использовать сертификаты SHA-256 для подписи приложений ClickOnce на платформе .NET Framework 4 и более ранних версий.

Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

Основные сведения

Поток CurrentCulture и CurrentUICulture между задачами

Сведения

Начиная с .NET Framework 4.6 System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture хранятся в System.Threading.ExecutionContext потока, который проходит через асинхронные операции. Это означает, что изменения System.Globalization.CultureInfo.CurrentCulture или System.Globalization.CultureInfo.CurrentUICulture будут отражены в задачах, которые позже выполняются асинхронно. Это отличается от поведения предыдущих версий .NET Framework (которые во всех асинхронных задачах сбрасывали System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture).

Предложение

Приложения, которых коснулось это изменение, могут обойти его, явно задав System.Globalization.CultureInfo.CurrentCulture или System.Globalization.CultureInfo.CurrentUICulture в качестве первой операции в асинхронной задаче. Кроме того, можно выбрать прежнее поведение (без потока System.Globalization.CultureInfo.CurrentCulture/System.Globalization.CultureInfo.CurrentUICulture) путем установки следующего переключателя совместимости:

AppContext.SetSwitch("Switch.System.Globalization.NoAsyncCurrentCulture", true);

Эта проблема была устранена с помощью WPF в .NET Framework 4.6.2. Она также была устранена в .NET Framework версий 4.6 и 4.6.1 посредством KB 3139549. Приложения, предназначенные для .NET Framework 4.6 или более поздней версии, автоматически получают правильное поведение в приложениях WPF — System.Globalization.CultureInfo.CurrentCulture/System.Globalization.CultureInfo.CurrentUICulture) будет сохранено в операциях диспетчера.

Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

Имена событий в трассировке событий Windows не должны отличаться друг от друга только суффиксами "Start" или "Stop"

Сведения

В .NET Framework 4.6 и 4.6.1 среда выполнения вызывает исключение ArgumentException, когда имена двух событий в трассировке событий Windows отличаются только суффиксами Start или Stop (например, когда имя одного события LogUser, а другого — LogUserStart). В этом случае среда выполнения не может определить источник событий и, соответственно, сделать запись в журнале.

Предложение

Чтобы предотвратить возникновение исключения, убедитесь, что имена событий отличаются не только суффиксами Start или Stop. Это требование снято в .NET Framework 4.6.2 и более поздних версий. Среда выполнения может устранить неоднозначность имен событий, которые отличаются только суффиксами Start и Stop.

Имя. Значение
Область Microsoft Edge
Версия 4,6
Тип Изменение целевой платформы

Entity Framework

Построение EDMX Entity Framework с помощью Visual Studio 2013 может завершиться ошибкой MSB4062, если используются задачи EntityDeploySplit или EntityClean

Сведения

Инструменты MSBuild 12.0 (в составе Visual Studio 2013) изменили расположение файлов MSBuild, что привело к недействительности старых файлов целей построения Entity Framework. В результате задачи EntityDeploySplit и EntityClean завершаются ошибкой, так как они не могут найти Microsoft.Data.Entity.Build.Tasks.dll. Обратите внимание, что это нарушение возникает вследствие изменения набора инструментов (MSBuild и Visual Studio), а не из-за изменения платформы .NET Framework. Оно происходит только при обновлении средств разработчика, а не просто при обновлении .NET Framework.

Предложение

Начиная с .NET Framework 4.6 файлы целей построения Entity Framework предназначены для работы с новым макетом MSBuild. Проблема будет решена после обновления до этой версии. Кроме того, это решение можно использовать для исправления файлов целей построения напрямую.

Имя. Значение
Область Основная
Версия 4.5.1
Тип Изменение целевой платформы

JIT

Инструкция IL ret недопустима в области try

Сведения

В отличие от JIT-компилятора JIT64, компилятор RyuJIT (в .NET Framework 4.6) не разрешает инструкцию IL ret в области try. Возврат из области try запрещен в спецификации ECMA-335, и ни один известный управляемый компилятор не создает такие IL. Однако компилятор JIT64 выполнит такие IL, если они созданы с помощью порождения отражения.

Предложение

Если приложение создает IL, который включает в себя код операции ret в области try, это приложение можно нацелить на платформу .NET Framework 4.5, чтобы использовать старый JIT-компилятор и избежать этой проблемы. Кроме того, создаваемый IL-код можно обновить, чтобы он возвращался после области try.

Имя. Значение
Область Microsoft Edge
Версия 4,6
Тип Изменение целевой платформы

Новый 64-разрядный JIT-компилятор в .NET Framework 4.6

Сведения

Начиная с .NET Framework 4.6, для JIT-компиляции используется новый 64-разрядный компилятор JIT. В некоторых случаях вызывается непредвиденное исключение или наблюдается другое поведение, отличное от поведения при выполнении приложения с использованием 32-разрядного компилятора или старого 64-разрядного JIT-компилятора. Это изменение не влияет на 32-разрядный компилятор JIT. Известные различия включают в себя следующее.

  • При определенных условиях операция распаковки может вызывать исключение NullReferenceException в сборках выпусков с включенной оптимизацией.
  • В некоторых случаях выполнение рабочего кода в большом теле метода может вызывать исключение StackOverflowException.
  • При определенных условиях в сборках выпусков передаваемые методу структуры обрабатываются как ссылочные типы, а не типы значений. Одним из проявлений этой проблемы является отображение отдельных элементов коллекции в непредвиденном порядке.
  • При определенных условиях сравнение значений UInt16 с установленным старшим битом выполняется неверно, если включена оптимизация.
  • При определенных условиях, особенно при инициализации значений массивов, инициализация памяти инструкцией OpCodes.Initblk IL может инициализировать память неправильным значением. Это может привести либо к необработанному исключению, либо к неправильным выходным данным.
  • В некоторых редких случаях условная поразрядная проверка может возвращать неверное значение типа Boolean или вызывать исключение, если включены оптимизации компилятора.
  • При определенных условиях, если инструкция if используется для проверки условия перед входом в блок try и на выходе из блока try, и такое же условие вычисляется в блоке catch или finally, новый 64-разрядный JIT-компилятор удаляет условие if из блока catch или finally при оптимизации кода. В результате код внутри инструкции if в блоке catch или finally выполняется безусловно.

Предложение

Устранение известных проблем
При возникновении перечисленных выше проблем их можно решить, выполнив одно из следующих действий.

  • Обновление до .NET Framework 4.6.2. Новый 64-разрядный компилятор, входящий в состав .NET Framework 4.6.2, устраняет все эти известные проблемы.

  • Обновление Windows до актуального состояния при запуске Центра обновления Windows. Обновления служб до .NET Framework 4.6 и 4.6.1 решают все эти проблемы, кроме исключения NullReferenceException при распаковке-преобразовании.

  • Компиляция с помощью старого 64-разрядного JIT-компилятора. Дополнительные сведения о том, как это сделать, см. в разделе Устранение других проблем. Устранение других проблем
    При возникновении любых других различий в поведении между кодом, скомпилированным с помощью старого и нового 64-разрядных JIT-компиляторов, или между отладочной и окончательной версиями приложения, которые обе скомпилированы новым 64-разрядным JIT-компилятором, можно выполнить следующие действия для компиляции приложения с помощью старого 64-разрядного JIT-компилятора.

  • Для каждого отдельного приложения можно добавить элемент < в файл конфигурации приложения. Следующее действие отключает компиляцию с помощью нового 64-разрядного JIT-компилятора и вместо этого использует устаревший 64-разрядный JIT-компилятор.

    <?xml version ="1.0"?>
    <configuration>
      <runtime>
       <useLegacyJit enabled="1" />
      </runtime>
    </configuration>
    
  • Для каждого отдельного пользователя можно добавить значение REG_DWORD с именем useLegacyJit в раздел реестра HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework. Значение 1 включает устаревший 64-разрядный JIT-компилятор; значение 0 отключает его и включает новый 64-разрядный JIT-компилятор.

  • Для каждого отдельного компьютера можно добавить значение REG_DWORD с именем useLegacyJit в раздел реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework. Значение 1 включает устаревший 64-разрядный JIT-компилятор; значение 0 отключает его и включает новый 64-разрядный JIT-компилятор. Можно также сообщить нам об обнаруженной проблеме, обратившись в службу Microsoft Connect.

Имя. Значение
Область Microsoft Edge
Версия 4,6
Тип Изменение целевой платформы

Сеть

Проверка OID EKU сертификата

Сведения

Начиная с .NET Framework 4.6 классы SslStream или ServicePointManager выполняют проверку идентификатора объекта (OID) расширенного использования ключа (EKU). Расширение расширенного использования ключа (EKU) — это коллекция идентификаторов объекта (OID), которые указывают приложения, использующие ключ. При проверке OID EKU используются обратные вызовы удаленного сертификата, чтобы у удаленного сертификата были правильные OID для указанных целей.

Предложение

Если это изменение нежелательно, можно отключить проверку OID сертификата EKU, добавив следующий параметр в <AppContextSwitchOverrides> в ` файле конфигурации приложения:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.Net.DontCheckCertificateEKUs=true" />
</runtime>

Внимание

Этот параметр предоставляется исключительно для обратной совместимости. Его использование в других целях не рекомендуется.

Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

В System.Net.ServicePointManager и System.Net.Security.SslStream поддерживаются только протоколы Tls 1.0, 1.1 и 1.2

Сведения

Начиная с версии .NET Framework 4.6, классы ServicePointManager и SslStream могут использовать только один из трех протоколов: Tls1.0, Tls1.1 или Tls1.2. Протокол SSL 3.0 и шифрование RC4 не поддерживаются.

Предложение

Рекомендуется обновить приложения на стороне сервера для использования Tls1.0, Tls1.1 или Tls1.2. Если это невозможно, или если клиентские приложения не работают, можно использовать класс System.AppContext, чтобы отказаться от этой функции одним из двух способов.

  • Путем программной установки параметров совместимости в System.AppContext, как описано здесь.
  • путем добавления следующей строки в раздел <runtime> файла app.config:
<AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=true"/>
Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

TLS 1.x по умолчанию передает флаг SCH_SEND_AUX_RECORD базовому API SCHANNEL

Сведения

При использовании TLS 1.x .NET Framework зависит от базового интерфейса API Windows SCHANNEL. Начиная с .NET Framework 4.6 флаг SCH_SEND_AUX_RECORD передается SCHANNEL по умолчанию. В результате SCHANNEL разделяет данные для шифрования на две отдельные записи. В первой — один байт, а во второй — n-1 байт. В редких случаях это нарушает логику взаимодействия между клиентами и существующими серверами, которая предполагает, что данные находятся в одной записи.

Предложение

Если это изменение нарушает связь с существующим сервером, вы можете отключить отправку флага SCH_SEND_AUX_RECORD и восстановить предыдущее поведение, при котором данные не разделяются на две записи, добавив следующий переключатель в элемент <AppContextSwitchOverrides> в разделе <runtime> файла конфигурации приложения:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchSendAuxRecord=true" />
</runtime>

Внимание

Этот параметр предоставляется исключительно для обратной совместимости. Его использование в других целях не рекомендуется.

Имя. Значение
Область Microsoft Edge
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

Windows Communication Foundation (WCF)

Был изменен вызов метода CreateDefaultAuthorizationContext с аргументом NULL

Сведения

В .NET Framework 4.6 изменилась реализация System.IdentityModel.Policy.AuthorizationContext, возвращаемая вызовом к System.IdentityModel.Policy.AuthorizationContext.CreateDefaultAuthorizationContext(IList<IAuthorizationPolicy>) с нулевым аргументом authorizationPolicies.

Предложение

В редких случаях в приложениях WCF, которые используют настраиваемую проверку подлинности, могут возникать различия в поведении. В таких случаях прежнее поведение можно восстановить двумя способами.

  • Перекомпилируйте приложение для ориентации на версию .NET Framework, предшествующую 4.6. Для служб, размещенных в IIS, используйте элемент <httpRuntime targetFramework="x.x"> для выбора более ранней версии .NET Framework в качестве целевой платформы.

  • Добавьте следующую строку в раздел <appSettings> файла app.config.

    <add key="appContext.SetSwitch:Switch.System.IdentityModel.EnableCachedEmptyDefaultAuthorizationContext" value="true" />
    
Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

Windows Forms

Icon.ToBitmap успешно преобразует значки с кадрами PNG в растровые изображения

Сведения

Начиная с приложений, предназначенных для .NET Framework 4.6, метод Icon.ToBitmap успешно преобразует значки с кадрами PNG в объекты Bitmap.

В приложениях, предназначенных для платформа .NET Framework 4.5.2 и более ранних версий, метод создает ArgumentOutOfRangeException исключение, Icon.ToBitmap если объект Icon имеет кадры PNG.

Это изменение затрагивает приложения, которые компилируются повторно для платформы .NET Framework 4.6 и в которых реализуется специальная обработка исключения ArgumentOutOfRangeException, создаваемого при наличии кадров PNG в объекте Icon . При выполнении в .NET Framework 4.6 преобразование проходит успешно, исключение ArgumentOutOfRangeException больше не создается, и поэтому обработчик исключений больше не вызывается.

Предложение

Если такое поведение нежелательно, можно сохранить прежнее поведение, добавив в раздел <runtime> файла app.config следующий элемент:

<AppContextSwitchOverrides
value="Switch.System.Drawing.DontSupportPngFramesInIcons=true" />

Если файл app.config уже содержит элемент AppContextSwitchOverrides, новое значение следует объединить с атрибутом значения следующим образом:

<AppContextSwitchOverrides
value="Switch.System.Drawing.DontSupportPngFramesInIcons=true;<previous key>=<previous value>" />
Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

Windows Presentation Foundation (WPF)

CurrentCulture не сохраняется в операциях диспетчера WPF

Сведения

Начиная с версии .NET Framework 4.6, изменения System.Globalization.CultureInfo.CurrentCulture или System.Globalization.CultureInfo.CurrentUICulture, внесенные в операции System.Windows.Threading.Dispatcher, будут утеряны в конце операции диспетчеризации. Аналогичным образом, изменения System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture, внесенные за пределами операции Dispatcher, не будут учитываться при выполнении этой операции. С практической точки зрения это означает, что изменения System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture могут не передаваться между обратными вызовами пользовательского интерфейса WPF и другим кодом приложения WPF. Это связано с изменением в System.Threading.ExecutionContext, в результате которого System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture сохраняются в контексте выполнения, начиная с приложений, предназначенных для версии .NET Framework 4.6. Операции диспетчеризации WPF сохраняют контекст выполнения, который используется для запуска операции и восстановления предыдущего контекста при завершении операции. Поскольку System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture теперь являются частью этого контекста, внесенные в рамках операции диспетчеризации изменения не сохраняются вне этой операции.

Предложение

В приложениях, затронутых данным изменением, можно обойти эту проблему, сохранив System.Globalization.CultureInfo.CurrentCulture или System.Globalization.CultureInfo.CurrentUICulture в поле и проверив все тексты операций диспетчеризации (включая обработчики обратного вызова событий пользовательского интерфейса) на установку правильных значений System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture. Кроме того, поскольку изменение ExecutionContext, являющееся базовым для этого изменения WPF, влияет только на приложения, предназначенные для .NET Framework 4.6 или более поздних версий, это нарушение можно исключить путем нацеливания на .NET Framework 4.5.2. В приложениях, ориентированных на платформу .NET Framework 4.6 или более поздней версии, эту проблему можно обойти, установив следующий параметр совместимости:

AppContext.SetSwitch("Switch.System.Globalization.NoAsyncCurrentCulture", true);

Эта проблема была устранена с помощью WPF в .NET Framework 4.6.2. Она также была устранена в .NET Framework версий 4.6 и 4.6.1 посредством KB 3139549. Приложения, предназначенные для .NET Framework 4.6 или более поздней версии, автоматически получают правильное поведение в приложениях WPF — System.Globalization.CultureInfo.CurrentCulture/System.Globalization.CultureInfo.CurrentUICulture) будет сохранено в операциях диспетчера.

Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

Изменились параметры округления полей макета WPF

Сведения

Способ округления полей, а также их границ и фона, изменен. В результате этого изменения:

  • ширина или высота элементов может увеличиться или уменьшиться максимум на один пиксель;
  • расположение объекта может измениться максимум на один пиксель;
  • выровненные по центру элементы могут сместиться по вертикали или горизонтали максимум на один пиксель. По умолчанию новый макет включен только для приложений, предназначенных для .NET Framework 4.6.

Предложение

Поскольку это изменение, как правило, приводит к устранению обрезки правых или нижних элементов управления WPF при высоком разрешении, для приложений, предназначенных для более ранних версий .NET Framework, но выполняющихся в .NET Framework 4.6, можно выбрать это новое поведение, добавив следующую строку в раздел <runtime> файла app.config.

<AppContextSwitchOverrides value="Switch.MS.Internal.DoNotApplyLayoutRoundingToMarginsAndBorderThickness=false" />

Для приложений, предназначенных для .NET Framework 4.6, в которых требуется задать отрисовку элементов управления WPF с помощью прежнего алгоритма макета, можно добавить следующую строку в раздел <runtime> файла app.config:

<AppContextSwitchOverrides value="Switch.MS.Internal.DoNotApplyLayoutRoundingToMarginsAndBorderThickness=true" />
Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

XML, XSLT

XmlWriter вызывает недействительные суррогатные пары

Сведения

Для приложений с целевой платформой .NET Framework 4.5.2 или предыдущих версий запись недействительной суррогатной пары с помощью обработки резервного исключения не всегда вызывает исключение. Для приложений с целевой платформой .NET Framework 4.6 попытка записи недействительной суррогатной пары вызывает исключение System.ArgumentException.

Предложение

При необходимости этого прерывания можно избежать, выбрав в качестве целевой платформы .NET Framework 4.5.2 или более ранней версии. Кроме того, до записи недействительных суррогатных пар можно предварительно обработать их и преобразовать в допустимый xml.

Имя. Значение
Область Microsoft Edge
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

Проверка схемы XSD теперь правильно обнаруживает нарушения уникальных ограничений, если используются составные ключи и один ключ пуст

Сведения

В версиях платформы .NET Framework, предшествовавших версии 4.6, была ошибка, из-за которой проверка XSD не могла обнаруживать уникальные ограничения по составным ключам, если один из ключей был пуст. Эта проблема решена в .NET Framework 4.6. Это приведет к выполнению более правильной проверки, но также может привести к невозможности проверки некоторого XML-кода, которая осуществлялась раньше.

Предложение

Если требуется менее строгая проверка .NET Framework 4.0, проверяющее приложение может быть предназначено для версии 4.5 (или более ранней) платформы .NET Framework. Однако при изменении целевой платформы на .NET Framework 4.6 следует выполнить проверку кода, чтобы не проверять повторяющиеся составные ключи (как указано в описании этой проблемы).

Имя. Значение
Область Microsoft Edge
Версия 4,6
Тип Изменение целевой платформы

.NET Framework 4.6.1

Основные сведения

Изменение знака разделения пути в свойстве FullName объектов ZipArchiveEntry

Сведения

Для приложений, предназначенных для платформа .NET Framework версии 4.6.1 и более поздних версий, символ разделителя путей изменился с обратной косой черты ("\") на косую черту ("/") в FullName свойстве ZipArchiveEntry объектов, созданных перегрузками CreateFromDirectory метода. Изменение обеспечивает соответствие реализации .NET разделу 4.4.17.1 спецификации формата ZIP-файла и позволяет распаковывать ZIP-архивы в системах, отличных от Windows.
При распаковке ZIP-файла, созданного приложением, предназначенным для предыдущей версии платформы .NET Framework в операционных системах, отличающихся от Windows, таких как Macintosh, не удается сохранить структуру каталогов. Например, в Macintosh создается набор файлов, имя которого объединяет путь к каталогу, а также все символы обратной косой черты (\) и имя файла. В результате структура каталогов распакованных файлов не сохраняется.

Предложение

Влияние этого изменения на файлы .ZIP, которые распаковываются в операционной системе Windows API в пространстве имен платформа .NET FrameworkSystem.IO, должны быть минимальными, так как эти API могут легко обрабатывать косую черту ("/") или обратную косую черту ("\") в качестве символа разделителя путей.
Если такое изменение нежелательно, от него можно отказаться, добавив параметр конфигурации в раздел <runtime> файла конфигурации приложения. В следующем примере показан как раздел <runtime>, так и параметр отключения Switch.System.IO.Compression.ZipFile.UseBackslash:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.IO.Compression.ZipFile.UseBackslash=true" />
</runtime>

Кроме того, в приложениях, предназначенных для предыдущих версий .NET Framework, но выполняемых в .NET Framework 4.6.1 и более поздних версий, можно включить такое поведение, добавив параметр конфигурации в раздел <runtime> файла конфигурации приложения. Ниже показаны как раздел <runtime>, так и параметр включения функции Switch.System.IO.Compression.ZipFile.UseBackslash.

<runtime>
  <AppContextSwitchOverrides value="Switch.System.IO.Compression.ZipFile.UseBackslash=false" />
</runtime>
Имя. Значение
Область Microsoft Edge
Версия 4.6.1
Тип Изменение целевой платформы

Затронутые API

Windows Communication Foundation (WCF)

Привязка WCF с режимом безопасности TransportWithMessageCredential

Сведения

Начиная с платформа .NET Framework 4.6.1, привязка WCF, использующая режим безопасности TransportWithMessageCredential, можно настроить для получения сообщений без знака "to" для асимметричных ключей безопасности. По умолчанию заголовки без знака "to" будут отклоняться в платформа .NET Framework 4.6.1. Они будут приниматься только в случае перевода приложения на новый режим с помощью переключателя конфигурации Switch.System.ServiceModel.AllowUnsignedToHeader.

Предложение

Поскольку это возможность, включаемая пользователем, она не должна влиять на поведение существующих приложений.
Для включения или отключения нового поведения используйте следующий параметр конфигурации:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.ServiceModel.AllowUnsignedToHeader=true" />
</runtime>
Имя. Значение
Область Прозрачный режим
Версия 4.6.1
Тип Изменение целевой платформы

Затронутые API

X509CertificateClaimSet.FindClaims учитывает все аргументы claimType

Сведения

Если в приложениях, предназначенных для .NET Framework 4.6.1, набор утверждений X509 инициализируется из сертификата, имеющего несколько записей DNS в поле SAN, метод System.IdentityModel.Claims.X509CertificateClaimSet.FindClaims(String, String) пытается сопоставить аргумент claimType со всеми записями DNS. В приложениях, предназначенных для предыдущих версий .NET Framework, метод System.IdentityModel.Claims.X509CertificateClaimSet.FindClaims(String, String) пытается сопоставить аргумент claimType только с последней записью DNS.

Предложение

Это изменение затрагивает только приложения, предназначенные для .NET Framework 4.6.1. Это изменение можно отключить (или включить, если используются версии, предшествующие 4.6.1) с помощью параметра совместимости DisableMultipleDNSEntries.

Имя. Значение
Область Незначительный
Версия 4.6.1
Тип Изменение целевой платформы

Затронутые API

Windows Forms

Application.FilterMessage больше не создает исключение для реализаций IMessageFilter.PreFilterMessage с повторным входом

Сведения

До версии .NET Framework 4.6.1 при вызове FilterMessage(Message) с PreFilterMessage(Message), вызывающим System.Windows.Forms.Application.AddMessageFilter(IMessageFilter) или System.Windows.Forms.Application.RemoveMessageFilter(IMessageFilter) (с одновременным вызовом DoEvents()), возникало исключение System.IndexOutOfRangeException.

Начиная с приложений, предназначенных для платформа .NET Framework 4.6.1, это исключение больше не создается, а фильтры повторного входа, как описано выше, могут использоваться.

Предложение

Имейте в виду, что FilterMessage(Message) больше не вызывает исключение для поведения PreFilterMessage(Message) с повторным входом, как описано выше. Будут затронуты только приложения, предназначенные для .NET Framework 4.6.1. В приложениях, предназначенных для .NET Framework 4.6.1, можно отказаться от этого изменения (или в приложениях, предназначенных для более старых платформ, можно использовать изменение) с помощью параметра совместимости DontSupportReentrantFilterMessage.

Имя. Значение
Область Microsoft Edge
Версия 4.6.1
Тип Изменение целевой платформы

Затронутые API

Windows Presentation Foundation (WPF)

Вызовы System.Windows.Input.PenContext.Disable в системах с поддержкой сенсорного ввода могут вызвать исключение ArgumentException

Сведения

В некоторых случаях вызовы внутреннего метода System.Windows.Intput.PenContext.Disable в системах с поддержкой сенсорного ввода могут вызывать необработанное исключение T:System.ArgumentException из-за повторного входа.

Предложение

Эта проблема была устранена в .NET Framework 4.7. Чтобы это исключение не возникало, выполните обновление до версии платформы .NET Framework 4.7 или более поздней.

Имя. Значение
Область Microsoft Edge
Версия 4.6.1
Тип Изменение целевой платформы

.NET Framework 4.6.2

ASP.NET

HttpRuntime.AppDomainAppPath создает исключение NullReferenceException

Сведения

В платформе .NET Framework 4.6.2 среда выполнения создает исключение T:System.NullReferenceException при получении значения P:System.Web.HttpRuntime.AppDomainAppPath, которое содержит нуль-символы. В .NET Framework 4.6.1 и более ранних версий среда выполнения создает исключение T:System.ArgumentNullException.

Предложение

В ответ на это изменение можно выполнить одно из следующих действий:

  • обрабатывайте T:System.NullReferenceException, если приложение работает на платформе .NET Framework 4.6.2;
  • обновите систему до версии .NET Framework 4.7, в которой восстановлено прежнее поведение, то есть создается исключение T:System.ArgumentNullException.
Имя. Значение
Область Microsoft Edge
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

Основные сведения

Дешифратор AesCryptoServiceProvider предоставляет преобразование для повторного использования

Сведения

Начиная с приложений, предназначенных для .NET Framework 4.6.2, дешифратор AesCryptoServiceProvider возвращает преобразование, которое можно использовать повторно. Это преобразование повторно инициализируется после вызова System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[], Int32, Int32) и его можно использовать снова. В приложениях, предназначенных для более ранних версий платформы .NET Framework, попытка повторного использования дешифратора путем вызова System.Security.Cryptography.CryptoAPITransform.TransformBlock(Byte[], Int32, Int32, Byte[], Int32) после вызова System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[], Int32, Int32) приводит к исключению CryptographicException или к повреждению данных.

Предложение

Влияние этого изменения должно быть минимальным, поскольку это ожидаемое поведение. В приложениях, которые зависят от прежнего поведения, можно отказаться от его изменения, добавив следующий параметр конфигурации в раздел <runtime> файла конфигурации приложения:

<runtime>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.AesCryptoServiceProvider.DontCorrectlyResetDecryptor=true"/>
</runtime>

Кроме того, это поведение можно включить для приложений, предназначенных для предыдущих версий .NET Framework, но работающих под управлением .NET Framework 4.6.2 или более поздних версий. Для этого добавьте в раздел <runtime> файла конфигурации приложения следующий параметр:

<runtime>
<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.AesCryptoServiceProvider.DontCorrectlyResetDecryptor=false"/>
</runtime>
Имя. Значение
Область Незначительный
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

Вызовы к конструкторам ClaimsIdentity

Сведения

Начиная с .NET Framework 4.6.2 конструкторы ClaimsIdentity с параметром System.Security.Principal.IIdentity иначе задают свойство System.Security.Claims.ClaimsIdentity.Actor. Если аргумент System.Security.Principal.IIdentity является объектом ClaimsIdentity, а свойство System.Security.Claims.ClaimsIdentity.Actor этого объекта ClaimsIdentity не равно null, свойство System.Security.Claims.ClaimsIdentity.Actor присоединяется с помощью метода Clone(). В Framework 4.6.1 и более ранних версиях свойство System.Security.Claims.ClaimsIdentity.Actor прикреплено как существующая ссылка. В результате этого изменения, начиная с .NET Framework 4.6.2, свойство System.Security.Claims.ClaimsIdentity.Actor нового объекта ClaimsIdentity не равно свойству System.Security.Claims.ClaimsIdentity.Actor аргумента конструктора System.Security.Principal.IIdentity. В .NET Framework 4.6.1 и более ранних версиях они равны.

Предложение

Если такое поведение нежелательно, можно восстановить прежнее поведение, задав переключателю Switch.System.Security.ClaimsIdentity.SetActorAsReferenceWhenCopyingClaimsIdentity в файле конфигурации приложения значение true. Для этого требуется добавить следующую информацию в раздел <runtime> файла web.config:

<configuration>
  <runtime>
    <AppContextSwitchOverrides value="Switch.System.Security.ClaimsIdentity.SetActorAsReferenceWhenCopyingClaimsIdentity=true" />
  </runtime>
</configuration>
Имя. Значение
Область Microsoft Edge
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

Изменения нормализации путей

Сведения

Начиная с приложений, предназначенных для .NET Framework 4.6.2, был изменен способ нормализации путей в среде выполнения. Нормализация пути включает в себя изменение строки, обозначающей путь или файл, чтобы эта строка соответствовала допустимому пути в целевой операционной системе. Нормализация обычно включает в себя:

  • канонизацию разделителей компонентов и каталогов;
  • применение текущего каталога к относительному пути;
  • оценку относительного каталога (.) или родительского каталога (..) в пути;
  • обрезку указанных символов. Начиная с приложений, предназначенных для платформа .NET Framework 4.6.2, по умолчанию включены следующие изменения в нормализации пути:
    • Среда выполнения перекладывает нормализацию путей на функцию GetFullPathName операционной системы.
  • Нормализация больше не предусматривает обрезки окончания сегментов каталогов (например, пробела в конце имени каталога).
  • Поддержка синтаксиса пути устройства в режиме полного доверия, включая \\.\ и (для API-интерфейсов файлового ввода-вывода в mscorlib.dll) \\?\.
  • Среда выполнения не проверяет пути с синтаксисом устройства.
  • Поддерживается использование синтаксиса устройства для доступа к альтернативным потокам данных. Эти изменения улучшают производительность, позволяя методам получать доступ к ранее недоступным путям. Это изменение не влияет на приложения, предназначенные для .NET Framework 4.6.1 и более ранних версий, но работающие на платформе .NET Framework 4.6.2 или более новой версии.

Предложение

В приложениях, предназначенных для .NET Framework 4.6.2 или более поздней версии, данное изменение можно отключить и использовать устаревшую нормализацию, добавив следующее в раздел <runtime> файла конфигурации приложения:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=true" />
</runtime>

В приложениях, предназначенных для .NET Framework 4.6.1 или более ранней версии, но работающих на платформе .NET Framework 4.6.2 или более поздней версии, можно включить изменения в нормализацию пути, добавив следующую строку в раздел <runtime> файла конфигурации приложения:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=false" />
</runtime>
Имя. Значение
Область Незначительный
Версия 4.6.2
Тип Изменение целевой платформы

Поток CurrentCulture и CurrentUICulture между задачами

Сведения

Начиная с .NET Framework 4.6 System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture хранятся в System.Threading.ExecutionContext потока, который проходит через асинхронные операции. Это означает, что изменения System.Globalization.CultureInfo.CurrentCulture или System.Globalization.CultureInfo.CurrentUICulture будут отражены в задачах, которые позже выполняются асинхронно. Это отличается от поведения предыдущих версий .NET Framework (которые во всех асинхронных задачах сбрасывали System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture).

Предложение

Приложения, которых коснулось это изменение, могут обойти его, явно задав System.Globalization.CultureInfo.CurrentCulture или System.Globalization.CultureInfo.CurrentUICulture в качестве первой операции в асинхронной задаче. Кроме того, можно выбрать прежнее поведение (без потока System.Globalization.CultureInfo.CurrentCulture/System.Globalization.CultureInfo.CurrentUICulture) путем установки следующего переключателя совместимости:

AppContext.SetSwitch("Switch.System.Globalization.NoAsyncCurrentCulture", true);

Эта проблема была устранена с помощью WPF в .NET Framework 4.6.2. Она также была устранена в .NET Framework версий 4.6 и 4.6.1 посредством KB 3139549. Приложения, предназначенные для .NET Framework 4.6 или более поздней версии, автоматически получают правильное поведение в приложениях WPF — System.Globalization.CultureInfo.CurrentCulture/System.Globalization.CultureInfo.CurrentUICulture) будет сохранено в операциях диспетчера.

Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы

Затронутые API

Имена событий в трассировке событий Windows не должны отличаться друг от друга только суффиксами "Start" или "Stop"

Сведения

В .NET Framework 4.6 и 4.6.1 среда выполнения вызывает исключение ArgumentException, когда имена двух событий в трассировке событий Windows отличаются только суффиксами Start или Stop (например, когда имя одного события LogUser, а другого — LogUserStart). В этом случае среда выполнения не может определить источник событий и, соответственно, сделать запись в журнале.

Предложение

Чтобы предотвратить возникновение исключения, убедитесь, что имена событий отличаются не только суффиксами Start или Stop. Это требование снято в .NET Framework 4.6.2 и более поздних версий. Среда выполнения может устранить неоднозначность имен событий, которые отличаются только суффиксами Start и Stop.

Имя. Значение
Область Microsoft Edge
Версия 4,6
Тип Изменение целевой платформы

Поддержка длинных путей

Сведения

Начиная с приложений, ориентированных на .NET Framework 4.6.2, поддерживаются длинные пути (до 32 тыс. символов), а ограничение длины пути в 260 символов (или MAX_PATH) было удалено. Для приложений, которые перекомпилируются для использования в .NET Framework 4.6.2, кодовые пути, ранее вызывавшие исключение System.IO.PathTooLongException, когда путь превышал 260 символов, теперь будут вызывать исключение System.IO.PathTooLongException только при следующих условиях:

  • длина пути превышает MaxValue (32 767) символов;
  • операционная система возвращает COR_E_PATHTOOLONG или его эквивалент; Для приложений, предназначенных для .NET Framework 4.6.1 и более ранних версий, среда выполнения автоматически создает исключение System.IO.PathTooLongException, когда длина пути превышает 260 символов.

Предложение

Для приложений, предназначенных для .NET Framework 4.6.2, можно отказаться от поддержки длинного пути, добавив следующую строку в раздел <runtime> файла app.config:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.IO.BlockLongPaths=true" />
</runtime>

Для приложений, которые предназначены для более ранних версий .NET Framework, но выполняются в .NET Framework 4.6.2 или более поздней версии, можно включить поддержку длинного пути, добавив следующую строку в раздел <runtime> файла app.config:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.IO.BlockLongPaths=false" />
</runtime>
Имя. Значение
Область Незначительный
Версия 4.6.2
Тип Изменение целевой платформы

Более строгие проверки двоеточий в пути

Сведения

В .NET Framework 4.6.2 выполнен ряд изменений для поддержки ранее не поддерживаемых путей (по длине и формату). Исправлены проверки надлежащего синтаксиса разделителя диска (двоеточие), в результате появился побочный эффект в виде блокировки некоторых путей универсального кода ресурса (URI) в некоторых API-интерфейсах пути, где раньше это допускалось.

Предложение

При передаче универсального кода ресурса (URI) в соответствующий API сначала измените строку, чтобы она содержала допустимый путь.

  • Удалите схему из URL-адресов вручную (например, удалите file:// из URL-адресов).

  • Передайте универсальный код ресурса (URI) в класс Uri и используйте LocalPath.

Кроме того, вы можете отказаться от новой нормализации путей, установив для переключателя Switch.System.IO.UseLegacyPathHandling AppContext значение true.

Имя. Значение
Область Microsoft Edge
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

Безопасность

RSACng теперь правильно загружает ключи RSA нестандартного размера

Сведения

В версиях .NET Framework до 4.6.2 клиенты с нестандартным размером ключа для сертификатов RSA не могли получить доступ к этим ключам через методы расширения System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPublicKey(X509Certificate2) и System.Security.Cryptography.X509Certificates.RSACertificateExtensions.GetRSAPrivateKey(X509Certificate2). Выдается System.Security.Cryptography.CryptographicException с сообщением "Запрошенный размер ключа не поддерживается". В .NET Framework 4.6.2 эта проблема была устранена. Аналогичным образом ImportParameters(RSAParameters) и ImportParameters(RSAParameters) теперь работают с нестандартными размерами ключа, не выдавая исключение System.Security.Cryptography.CryptographicException.

Предложение

Если существует логика обработки исключений, которая полагается на предыдущее поведение, когда при использовании ключей нестандартного размера возникало исключение System.Security.Cryptography.CryptographicException, возможно, следует удалить эту логику.

Имя. Значение
Область Microsoft Edge
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

SignedXml.GetPublicKey возвращает RSACng в net462 (или lightup) без изменения целевой платформы

Сведения

Начиная с .NET Framework 4.6.2 конкретный тип объекта, возвращаемого методом SignedXml.GetPublicKey, изменен (без особенностей) с реализации CryptoServiceProvider на реализацию Cng. Это связано с изменениями реализации, предусматривающими использование certificate.PublicKey.Key вместо внутреннего certificate.GetAnyPublicKey с переадресацией к RSACertificateExtensions.GetRSAPublicKey.

Предложение

Начиная с приложений, выполняющихся в .NET Framework 4.7.1, вы можете использовать реализацию CryptoServiceProvider, используемую по умолчанию на платформе .NET Framework 4.6.1 и более ранних версий, добавив следующую конфигурацию в раздел runtime файла конфигурации приложения:

<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.Xml.SignedXmlUseLegacyCertificatePrivateKey=true" />
Имя. Значение
Область Microsoft Edge
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

Windows Communication Foundation (WCF)

При использовании реентерабельных служб может возникнуть взаимоблокировка

Сведения

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

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]

Предложение

Чтобы устранить эту проблему, выполните следующие действия:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
  • Установите последнее обновление для .NET Framework 4.6.2 или обновитесь до последней версии платформы .NET Framework. Это приведет к отключению потока ExecutionContext в OperationContext.Current. Это поведение можно настраивать. Это эквивалентно добавлению следующего параметра приложения в файл конфигурации:
<appSettings>
  <add key="Switch.System.ServiceModel.DisableOperationContextAsyncFlow" value="true" />
</appSettings>

Значение Switch.System.ServiceModel.DisableOperationContextAsyncFlow нельзя устанавливать на false для реентерабельных служб.

Имя. Значение
Область Незначительный
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

OperationContext.Current может возвращать значение NULL при вызове в конструкции Using

Сведения

OperationContext.Current может возвращать null и создавать NullReferenceException, если все следующие условия верны:

using (new OperationContextScope(OperationContext.Current))
{
    // OperationContext.Current is null.
    OperationContext context = OperationContext.Current;

    // ...
}

Предложение

Чтобы устранить эту проблему, выполните следующие действия:

  • Измените код следующим образом, чтобы создать экземпляр нового объекта, отличного nullCurrent от объекта:

    OperationContext ocx = OperationContext.Current;
    using (new OperationContextScope(OperationContext.Current))
    {
        OperationContext.Current = new OperationContext(ocx.Channel);
    
        // ...
    }
    
  • Установите последнее обновление для .NET Framework 4.6.2 или обновитесь до последней версии платформы .NET Framework. Это приведет к отключению потока ExecutionContext в OperationContext.Current и восстановлению поведения приложений WCF в .NET Framework 4.6.1 и более ранних версий. Это поведение можно настраивать. Это эквивалентно добавлению следующего параметра приложения в файл конфигурации:

    <appSettings>
      <add key="Switch.System.ServiceModel.DisableOperationContextAsyncFlow" value="true" />
    </appSettings>
    

    Если это изменение нежелательно и приложение зависит от выполнения контекста при переходе между контекстами операции, этот поток можно включить следующим образом:

    <appSettings>
      <add key="Switch.System.ServiceModel.DisableOperationContextAsyncFlow" value="false" />
    </appSettings>
    
Имя. Значение
Область Microsoft Edge
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

Защита транспорта WCF поддерживает сертификаты, сохраненные с помощью CNG

Сведения

Начиная с приложений, предназначенных для .NET Framework 4.6.2, защита транспорта WCF поддерживает сертификаты, сохраненные с использованием библиотеки шифрования Windows (CNG). Эта поддержка ограничивается сертификатами с открытым ключом, длина экспоненты которого не превышает 32 бита. Если приложение предназначено для .NET Framework 4.6.2, эта функция включена по умолчанию. В более ранних версиях платформы .NET Framework попытка использовать сертификаты X509 с поставщиком хранилища ключей CSG вызывала исключение.

Предложение

Для приложений, которые предназначены для .NET Framework 4.6.1 и более ранних версий, но работают в .NET Framework 4.6.2, можно включить поддержку сертификатов CNG, добавив следующую строку в раздел <runtime> файла app.config или web.config:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.IdentityModel.DisableCngCertificates=false" />
</runtime>

Это также можно сделать программно с помощью следующего кода:

private const string DisableCngCertificates = @"Switch.System.IdentityModel.DisableCngCertificate";

AppContext.SetSwitch(disableCngCertificates, false);
Const DisableCngCertificates As String = "Switch.System.IdentityModel.DisableCngCertificates"
AppContext.SetSwitch(disableCngCertificates, False)

Обратите внимание, что из-за этого изменения любой код обработки исключений, который зависит от неудачной попытки инициировать защищенное взаимодействие с сертификатом CNG, больше не будет выполняться.

Имя. Значение
Область Незначительный
Версия 4.6.2
Тип Изменение целевой платформы

Windows Forms

Неправильная реализация MemberDescriptor.Equals

Сведения

Исходная реализация метода MemberDescriptor.Equals сравнивает два разных свойства строки из объектов для сравнения: имя категории и строка описания. Исправление заключается в сравнении Category первого объекта с Category второго объекта, и Description первого объекта с Description второго.

Предложение

Если приложение зависит от того, что MemberDescriptor.Equals иногда возвращает значение false, когда дескрипторы эквивалентны, и вы используете .NET Framework 4.6.2 или более поздней версии, у вас есть несколько вариантов:

  • Изменения в коде для сравнения полей Category и Description вручную в дополнение к вызову метода MemberDescriptor.Equals.
  • Откажитесь от этого изменения, добавив следующее значение в файл app.config:
<runtime>
  <AppContextSwitchOverrides value="Switch.System.MemberDescriptorEqualsReturnsFalseIfEquivalent=true" />
</runtime>

Если ваше приложение предназначено для .NET Framework 4.6.1 или более ранней версии и выполняется на .NET Framework 4.6.2 или более поздней версии и вы хотите включить это изменение, вы можете указать для переключателя совместимости значение false, добавив следующее значение в файл app.config:

<runtime>
  <AppContextSwitchOverrides value="Switch.System.MemberDescriptorEqualsReturnsFalseIfEquivalent=false" />
</runtime>
Имя. Значение
Область Microsoft Edge
Версия 4.6.2
Тип Изменение целевой платформы

Затронутые API

Windows Presentation Foundation (WPF)

CurrentCulture не сохраняется в операциях диспетчера WPF

Сведения

Начиная с версии .NET Framework 4.6, изменения System.Globalization.CultureInfo.CurrentCulture или System.Globalization.CultureInfo.CurrentUICulture, внесенные в операции System.Windows.Threading.Dispatcher, будут утеряны в конце операции диспетчеризации. Аналогичным образом, изменения System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture, внесенные за пределами операции Dispatcher, не будут учитываться при выполнении этой операции. С практической точки зрения это означает, что изменения System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture могут не передаваться между обратными вызовами пользовательского интерфейса WPF и другим кодом приложения WPF. Это связано с изменением в System.Threading.ExecutionContext, в результате которого System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture сохраняются в контексте выполнения, начиная с приложений, предназначенных для версии .NET Framework 4.6. Операции диспетчеризации WPF сохраняют контекст выполнения, который используется для запуска операции и восстановления предыдущего контекста при завершении операции. Поскольку System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture теперь являются частью этого контекста, внесенные в рамках операции диспетчеризации изменения не сохраняются вне этой операции.

Предложение

В приложениях, затронутых данным изменением, можно обойти эту проблему, сохранив System.Globalization.CultureInfo.CurrentCulture или System.Globalization.CultureInfo.CurrentUICulture в поле и проверив все тексты операций диспетчеризации (включая обработчики обратного вызова событий пользовательского интерфейса) на установку правильных значений System.Globalization.CultureInfo.CurrentCulture и System.Globalization.CultureInfo.CurrentUICulture. Кроме того, поскольку изменение ExecutionContext, являющееся базовым для этого изменения WPF, влияет только на приложения, предназначенные для .NET Framework 4.6 или более поздних версий, это нарушение можно исключить путем нацеливания на .NET Framework 4.5.2. В приложениях, ориентированных на платформу .NET Framework 4.6 или более поздней версии, эту проблему можно обойти, установив следующий параметр совместимости:

AppContext.SetSwitch("Switch.System.Globalization.NoAsyncCurrentCulture", true);

Эта проблема была устранена с помощью WPF в .NET Framework 4.6.2. Она также была устранена в .NET Framework версий 4.6 и 4.6.1 посредством KB 3139549. Приложения, предназначенные для .NET Framework 4.6 или более поздней версии, автоматически получают правильное поведение в приложениях WPF — System.Globalization.CultureInfo.CurrentCulture/System.Globalization.CultureInfo.CurrentUICulture) будет сохранено в операциях диспетчера.

Имя. Значение
Область Незначительный
Версия 4,6
Тип Изменение целевой платформы