INotifyPropertyChanged:在调用之前还是之后都要编组?

时间:2019-05-07 02:50:30

标签: c# wpf data-binding

我有一个应用程序可以修改后台线程中的数据绑定对象,以避免在UI线程上长时间运行操作。

WPF中的数据绑定系统自动将INotifyPropertyChanged.PropertyChanged事件更改为UI线程,因此这通常不是问题。

当我将引发ICommand.CanExecuteChanged的事件处理程序添加到INotifyPropertyChanged.PropertyChanged事件时,我得到了一个跨线程InvalidOperationException

当我举起INotifyPropertyChanged.PropertyChanged或我举起ICommand.CanExecuteChanged时,我应该编组回到UI线程吗?

这两个选项都有优点和缺点,但是两种方法都可行。 什么是最佳实践?

以下是每种方法的优缺点,因此您了解我在问的原因: pros and cons 这些只是我头上的一些东西。我想知道什么是最佳选择,为什么。目前,我认为在处理程序中进行编组是一个不错的选择,但仍然不能与我配合。也许有一个我忽略的选项。

1 个答案:

答案 0 :(得分:0)

所以我假设您的代码类似于

class MyCustomCommand : ICommand
{
    public event EventHandler CanExecuteChanged;

    // the rest of the ICommand interface members implemented    

    private void HandlePropertyChanged(object sender, NotifyPropertyChangedEventArgs e)
    {
        this.CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
}

在这种情况下,命令的CanExecuteChanged事件将在同一后台线程上触发。为什么这会导致跨线程异常,我不知道-您将必须提供更多代码来演示使用它们的上下文,包括如何绑定绑定。

如果您必须编组到UI线程,则我将编组CanExecuteChanged事件的产生,因为我假设您希望在后台线程上保留其余代码。

var dispatcher = GetADispatcherForMarshallingToUI();
dispatcher.BeginInvoke((Action)(() => this.CanExecuteChanged?.Invoke(this, EventArgs.Empty)));