RaiseCanExecuteChanged COM изключение по време на навигация?

Актуализация

Качен примерен проект: https://github.com/subt13/BugSamples

Възпроизвеждах грешка, която възниква в Windows 10 UAP приложение, което използва рамката MVVMLight.

Получавам грешката по-долу по време на навигация, докато процесорът е под голямо натоварване (~20-25%) и страницата е „тежка“ (големи изображения, много контроли и т.н. и т.н.)

в System.Runtime.InteropServices.WindowsRuntime.ICommandAdapterHelpers.‹>c__DisplayClass2.b__3(Object sender, EventArgs e) в System.EventHandler.Invoke(Object sender, EventArgs e) в GalaSoft.MvvmLight.Command.RelayCommand.RaiseCanExecuteChanged() в RaiseExe cuteChangeRepo .ViewModel.MainViewModel.d__17.MoveNext()

В примера грешката възниква на RaiseCanExecuteChanged();

    private async void ExecuteLoadDataCommandAsync()
    {
        // cause the app to slow done.
        var data = await Task.Run(() => GetData()); 

        if (data != null)
        {
            this.Data.Clear();

            foreach (var item in data)
            {
                this.Data.Add(new AnotherVM(item));
            }
        }

        // have the select job command rerun its condition
        this.SelectCommand.RaiseCanExecuteChanged();
    }

    // slow down the page
    public List<DataItem> GetData()
    {
        var myList = new List<DataItem>();
        for (int i = 0; i < 100000; ++i)
        {
            myList.Add(new DataItem("Welcome to MVVM Light"));

        }

        return myList;
    }

Нищо специално не се случва по време на навигация, освен че командата, свързана с ExecuteLoadDataCommandAsync(), се извиква за зареждане на данни.

<Core:EventTriggerBehavior EventName="Loaded">
    <Core:InvokeCommandAction Command="{Binding LoadDataCommand}">
   </Core:InvokeCommandAction>
</Core:EventTriggerBehavior>

За да възпроизведете, просто превключете от една страница на друга бързо за няколко секунди и след това просто изчакайте. След не много време изключението ще бъде повдигнато.


person O.O    schedule 16.09.2015    source източник
comment
E_FAIL е само оценка на учителя за качеството на докладването на грешки в WinRT. Напълно безполезно е да се диагностицира основният проблем. Може да е проблем с нишката, винаги ненулев коефициент за това в async/await код. Но пак може да е всичко. Ще трябва да намерите надежден възпроизвеждащ сценарий, не планирайте да постигате нищо през следващата седмица.   -  person Hans Passant    schedule 17.09.2015
comment
@HansPassant - Да, работя върху това.   -  person O.O    schedule 17.09.2015
comment
Предполагам, че се причинява от бързо превключване от една страница на друга за няколко секунди и след това просто изчакване. - вашите async операции все още се изпълняват и когато завършат, те се опитват да взаимодействат с XAML дърво, което вече не е активно. За да коригирате, уверете се, че все още сте активната страница, преди да повдигнете събитията.   -  person Peter Torr - MSFT    schedule 19.09.2015
comment
Като зададете DataContext на null при напускане на главната страница (заменяйки OnNavigatedFrom(NavigationEventArgs)). Успях да поправя COM изключение от метода RaiseCanExecuteChanged(), НО сега получавам друго изключение E_FAIL от някъде другаде. Не знам как се отнася за вашето реално приложение, но може да се наложи да отмените зареждането, когато напускате страницата, или може би да използвате кеш, за да избегнете презареждане всеки път на данните.   -  person Vincent    schedule 23.09.2015
comment
Аз също подозирам, че е проблем с повторното влизане. Трябва да предпазите ExecuteLoadDataCommandAsync от повторно влизане и да добавите някаква логика за анулиране (така че RaiseCanExecuteChanged да не бъде уволнен излишно). Има много начини да направите това, някои се обсъждат тук.   -  person noseratio    schedule 24.09.2015
comment
@O.O Намерихте ли причината? Имам подобен проблем, който не разбирам.   -  person Amenti    schedule 26.04.2016
comment
@Amenti - вижте отговора ми.   -  person O.O    schedule 26.04.2016


Отговори (1)


В крайна сметка поправих проблема си, като добавих следното събитие към кода отзад.

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    this.DataContext = null;
    base.OnNavigatedFrom(e);
}
person O.O    schedule 26.04.2016