我们应该在UI线程中调用OnPropertyChanged吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我们应该在UI线程中调用OnPropertyChanged吗?相关的知识,希望对你有一定的参考价值。

在这个简单的例子中,我们可以在任何线程中读取Property StrTestExample。

我在同一篇文章中看到,它说OnPropertyChanged事件会自动封送到UI线程。所以我们可以在任何线程中设置StrTestExample并且UI可以更新。另外一篇文章说我们应该负责在UI线程中调用OnPropertyChaned。

这是对的吗?

来自msdn或其他地方的任何文件证明这一点?

public class ViewModelBase : INotifyPropertyChanged
    {

        private volatile string _strTestExample;

        public string StrTestExample
        {
            get { return _strTestExample; }
            set
            {
                if (_strTestExample != value)
                {
                    _strTestExample = value;
                    OnPropertyChanged(nameof(StrTestExample));
                }
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var propertyChanged = PropertyChanged;
            propertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }


    }
答案

我在同一篇文章中看到,它说OnPropertyChanged事件会自动封送到UI线程。所以我们可以在任何线程中设置StrTestExample,UI可以更新。另外一篇文章说我们应该负责在UI线程中调用OnPropertyChaned。这是对的吗?

前者。您可以从任何线程调用OnPropertyChanged并为属性引发PropertyChanged事件。该框架将为您处理编组。

您可以通过例如启动Task并在后台线程中执行的操作中设置属性来轻松地确认这一点,例如:

public class ViewModelBase : INotifyPropertyChanged
{
    public ViewModelBase()
    {
        Task.Run(()=> 
        {
            for(int i = 0; i < 5; ++i)
            {
                StrTestExample = i.ToString();
                Thread.Sleep(2000);
            }
        });
    }
    private string _strTestExample;
    public string StrTestExample
    {
        get { return _strTestExample; }
        set
        {
            if (_strTestExample != value)
            {
                _strTestExample = value;
                OnPropertyChanged(nameof(StrTestExample));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

请注意,从背景更新源集合是一个不同的故事。

以上是关于我们应该在UI线程中调用OnPropertyChanged吗?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Java 文档中指定应该从非 UI 线程调用方法

本机调用阻塞主线程

从单例管理器类发布到 UI 线程

在单独的线程中调用 MFC UI 类上的方法

如何从工作线程中调用 UI 线程上的方法? [复制]

android AsyncTask的方法在哪几个线程中调用