1

INotifyPropertyChanged最近、クロススレッドの問題をスローするワーカースレッドからプロパティを実装および更新するタイプのバインディングでテストしています。

サンプルコードは次のとおりです。

public class MyViewModel : INotifyPropertyChanged
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    OnPropertyChanged("Name");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {

            PropertyChangedEventHandler hanlder = PropertyChanged;
           if(hanlder != null)
                hanlder(this, new PropertyChangedEventArgs(propertyName));

        }
    }

上記のビューモデルは、Windows フォームのラベル テキストにバインドされ、ワー​​カー スレッドからラベル値を更新しています。

ワーカー スレッドから label1 テキストを更新すると、クロス スレッドの問題が発生します。

public partial class MainForm : Form
{
    private MyViewModel _myViewModel = new MyViewModel();
    public MainForm()
    {
        InitializeComponent();
        Btn1.Click += Btn1_Click;
        label1.DataBindings.Add("Text", _myViewModel, "Name");

    }

    private void Btn1_Click(object sender, EventArgs e)
    {
        Task.Factory.StartNew(() =>
        {
            _myViewModel.Name = "Updating from worker thread!"; It causes cross thread issue
        });
    }
}

これまでのところ、ワーカー スレッドからの UI の更新が原因であると考えられます。ボタンクリック方法を変更せずにスレッドセーフにするための回避策はありますか。つまり、おそらくビューモデルでスレッドセーフにします。

4

2 に答える 2

-1

CheckForIllegalCrossThreadCalls を試しましたか?
このような :

private void Btn1_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        CheckForIllegalCrossThreadCalls = false; 
        _myViewModel.Name = "Updating from worker thread!"; It causes cross thread issue
        CheckForIllegalCrossThreadCalls = true;

    });
}

それが最善の方法だとは言いませんが、スレッドを操作するときにうまくいきます

編集 :

private void Btn1_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        _myViewModel.Invoke((MethodInvoker)(() => _myViewModel.Name = "Updating from worker thread!"; ));
    });
}
于 2016-04-18T07:45:21.990 に答える