Исключения только для релизов для раскадровки UWP и CallMethodAction - PullRequest
0 голосов
/ 05 октября 2018

Я отлаживаю фрагмент кода, который использует CallMethodAction для запуска раскадровки в приложении UWP.Мой VS обновлен до последней версии (15.8.6).Я получаю ошибку от VS 2017:

Не удается найти метод с именем Begin в объекте типа Windows.UI.Xaml.Media.Animation.Storyboard, который соответствует ожидаемой подписи.

Я должен вручную включить исключения в VS, в противном случае он просто покажет:

Необработанное исключение в 0x5B79DC3C (Windows.UI.Xaml.dll) в app.exe: 0xC000027B:Возникла внутренняя исключительная ситуация приложения (параметры: 0x1DF30E70, 0x00000003).произошло

После нескольких попыток я обнаружил, что:

  1. Раскадровка отлично работает в отладке.Только сбой в выпуске.
  2. Я иду к определению Раскадровки, подпись Бегина:
public void Begin();

Что выглядит хорошо.(И это работает при отладке ...)

Storyborad и DataTriggerBehavior настроены так:

<Storyboard x:Name="ShowOverlay">
  ... // doesn't really matter
</Storyboard>

<core:DataTriggerBehavior Binding="{Binding LogUploadStatus, Converter={StaticResource LogUploadStatusToBoolConverter}, ConverterParameter={StaticResource LogUploadStatusIdle}}" Value="False">
  <core:CallMethodAction TargetObject="{Binding ElementName=ShowOverlay}" MethodName="Begin" />
</core:DataTriggerBehavior>

У кого-нибудь есть идея, почему исключение происходит только в релизе?

1 Ответ

0 голосов
/ 05 октября 2018

Как правило, вместо CallMethodAction вы можете использовать ControlStoryboardAction.Это специфическое поведение, созданное для поддержки управления элементом Storyboard:

<Storyboard x:Name="ShowOverlay">
  ...
</Storyboard>

<core:DataTriggerBehavior Binding="{Binding LogUploadStatus, Converter={StaticResource LogUploadStatusToBoolConverter}, ConverterParameter={StaticResource LogUploadStatusIdle}}" Value="False">
  <core:ControlStoryboardAction Storyboard="{StaticResource ShowOverlay}"
                                ControlStoryboardOption="Play" />
</core:DataTriggerBehavior>

Что касается того, почему ControlMethodAction не работал, в режиме Release компилятор .NET Native удаляет все, что не используется, так чтоэто может минимизировать размер получаемой сборки, а также оптимизировать производительность.К сожалению, это может вызвать проблемы при использовании отражения для доступа к типам и элементам, к которым нет прямого доступа.

В этом случае метод Storyboard.Begin() никогда не используется напрямую, и если вы проверите исходный код из CallMethodAction, вы можете обнаружить, что действие использует отражение для обнаружения методов в TargetObject:

foreach (MethodInfo method in this.targetObjectType.GetRuntimeMethods())
{
    ...
}

К счастью, есть способ заставить компилятор .NET Native напрямую включать тип и помочь вам сделать это, вы можете использовать MissingMetadataException Troubleshooter (названо тем, что большую часть времени это исключение вы получите, когда тип отсутствует).

В этом случае я указал полный путь к Storyboard (Windows.UI.Xaml.Media.Animation.Storyboard) введите Один тип раздел инструмента:

I reflect on a single type

И ниже выбрал Доступ к элементам или активация и Только открытые типы и члены .

В правой части инструмент сгенерирует объявление <Type>, которое необходимо добавить к элементу <Application> в * 1047.Файл * default.rd.xml , который вы можете найти в папке Properties Проект UWP.В нашем случае результат может выглядеть следующим образом (исключая комментарии):

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Application>
    <Assembly Name="*Application*" Dynamic="Required All" />

    <Type Name="Windows.UI.Xaml.Media.Animation.Storyboard" Dynamic="Required Public" />    
  </Application>
</Directives>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...