Должны ли мы вызывать OnPropertyChanged в потоке пользовательского интерфейса? - PullRequest
0 голосов
/ 13 сентября 2018

В этом простом примере мы можем прочитать свойство StrTestExample в любом потоке.

В той же статье я вижу, что в нем говорится, что событие OnPropertyChanged автоматически маршалируется в поток пользовательского интерфейса.Таким образом, мы можем установить StrTestExample в любом потоке, и пользовательский интерфейс может обновляться.Также в другой статье говорится, что мы должны взять на себя ответственность за вызов 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));
        }


    }

1 Ответ

0 голосов
/ 13 сентября 2018

Я вижу в той же статье, он говорит, что событие OnPropertyChanged автоматически маршалируется в поток пользовательского интерфейса.Таким образом, мы можем установить StrTestExample в любом потоке, и пользовательский интерфейс может обновляться.Также в другой статье говорится, что мы должны взять на себя ответственность за вызов 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));
}

Обратите внимание, что обновление исходной коллекции из фона - это совсем другая история.

...