.Net Проблемы миграции х86 проектов на х64 OS и способы их решения

Проблема 1: «Microsoft Silverlight cannot be used in browser running in 64bit mode»

С данной проблемой чаще всего можно столкнуться в WinForms приложении, содержащем в себе WebBrowser Control. При попытке отобразить в этом контроле Silverlight страницу, в Windows 7 x64 пользователь вместо страницы увидит указанную ошибку, в то время как в любой x86 операционной системе это же приложение будет работать идеально.

В чем причина? А причина элементарна — Microsoft Silverlight не поддерживает работу в x64bit процессе. Если ваше приложение скомпилировано под AnyCPU target platform, оно будет запушено как x64 приложение на х64 OS и Silverlight, способный работать только в 32-bit процессе, просто не будет работать.

Решение: Как Вы вероятно уже догадались, единственный вариант решение этой проблемы на текущий момент – это компилировать приложение по x86 платформу принудительно.

Проблема 2: В x64 OS при изменении размера окна приложения не перерисовываются и/или не меняют свой размер некоторые вложенный контролы, хотя под x86 OS такой проблемы не наблюдалось.

Источник этой проблемы детально описан у Микрософт в этой статье:
Deeply nested controls do not resize properly when their parents are resized

В двух словах суть проблемы с следующем: при изменении размера формы, она вызывает SetWindowPos чтобы изменить размер своим дочерним контролов. Каждый дочерний контрол получает сообщение WM_WINDOWPOSCHANGED, в результате которого вызывает SetWindowPos уже для своих дочерних контролов следующего уровня. Каждый вызов SetWindowPos выполняется в режиме ядра, что в конечном счете приводит к переполнению стека ядра (kernel stack overflow) которое перехватывается и молча гасится дабы не показывать в результате «синий экран смерти». А как итог, размеры глубоко вложенных контролов остаются не измененными и сами контролы – не перерисованными.

На самом деле это проблема присуща не только x64 OS, но и x86 при достаточном количестве уровней вложенности. Но почему же тогда приложение отлично работает в 32bit OS и отказывается так же исправно работать в 64bit OS? Да все дело в том, что при переходе на 64-bit архитектуру размер указателя вырос с 4 байт до 8 байт. А что стало с размером стека ядра? Догадались? Правильно – он остался точно таким же. Вот и получается, что если для x64 максимальное поддерживаемое число уровней вложенности составляет примерно 20-25, то для x86 архитектуры это число будет в 2 раза выше 40-50.

Решение: Если не считать банального изменения дизайна так, чтобы уменьшить число уровней вложенности, наиболее безболезненное и простое решение будет разорвать в ключевых местах рекурсию вызова OnSizeChanged заменив ее на множественные kernel-to-user mode callbacks:

protected override void OnSizeChanged(EventArgs e) {
 if (Handle != null) { BeginInvoke(new Action(base.OnSizeChanged), e); } 
 }


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.