【问题标题】:RaiseCanExecuteChanged COM Exception during Navigation?导航期间出现 RaiseCanExecuteChanged COM 异常?
【发布时间】:2015-12-13 13:07:52
【问题描述】:

更新

上传的示例项目:https://github.com/subt13/BugSamples

我重现了在使用 MVVMLight 框架的 Windows 10 UAP 应用程序中发生的错误。

当 CPU 处于重负载 (~20-25%) 并且页面“很重”(大图像、大量控件等)时,我在导航期间收到以下错误

在 System.Runtime.InteropServices.WindowsRuntime.ICommandAdapterHelpers.c__DisplayClass2.b__3(对象 发件人,EventArgs e)在 System.EventHandler.Invoke(对象发件人, EventArgs e) 在 GalaSoft.MvvmLight.Command.RelayCommand.RaiseCanExecuteChanged() 在 RaiseExecuteChangeRepo.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>

要重现,只需从一页快速切换到另一页几秒钟,然后等待。不久之后就会引发异常。

【问题讨论】:

  • E_FAIL 只是 WinRT 中错误报告质量的教师评分。诊断根本问题完全没有用。它可能是一个线程问题,在异步/等待代码中总是非零几率。但话又说回来,它可能是任何东西。你必须找到一个可靠的重现场景,下周不要计划完成任何事情。
  • @HansPassant - 是的,正在努力。
  • 我的猜测是“从一个页面快速切换到另一个页面几秒钟然后等待”引起的。 - 您的async 操作仍在运行,当它们完成时,它们会尝试与不再活动的 XAML 树进行交互。要解决此问题,请确保在引发事件之前您仍然是活动页面。
  • 通过在离开主页面时将 DataContext 设置为 null(覆盖 OnNavigatedFrom(NavigationEventArgs))。我已经能够从 RaiseCanExecuteChanged() 方法修复 COM 异常,但是,我现在从其他地方得到另一个 E_FAIL 异常。我不知道它如何应用于您的实际应用程序,但您可能必须在离开页面时取消加载,或者可能使用缓存来避免每次数据都重新加载。
  • 我也怀疑这是重入问题。您应该保护ExecuteLoadDataCommandAsync 避免重新进入并添加一些取消逻辑(这样RaiseCanExecuteChanged 就不会被多余地触发)。有很多方法可以做到这一点,其中一些在here进行讨论。

标签: c# windows-runtime async-await mvvm-light win-universal-app


【解决方案1】:

我最终通过将以下事件添加到后面的代码来解决我的问题。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-06
    • 2016-12-28
    • 2016-07-30
    • 2022-01-25
    • 1970-01-01
    • 2017-07-17
    • 2020-06-07
    • 1970-01-01
    相关资源
    最近更新 更多