【问题标题】:Background thread updates value, OnPropertyChanged invoke on noneui thread so get error [duplicate]后台线程更新值,在非 UI 线程上调用 OnPropertyChanged,因此出现错误 [重复]
【发布时间】:2019-08-30 08:21:29
【问题描述】:

我在后台线程更新值,在后台线程调用 OnPropertyChanged,所以更新 ui 出错 我可以使用 CheckForIllegalCrossThreadCalls = false; 但是有没有更好的方法来解决这个问题?

public partial class Form1 : Form
{        
    public Form1()
    {
        InitializeComponent();

        label1.DataBindings.Add("Text", a, "Count");
    }

    AAA a = new AAA();

    private void button1_Click(object sender, EventArgs e)
    {
        Task.Run(() => { a.Count++; }); //get error
        //a.Count++;   this ok
    }
}

class AAA : INotifyPropertyChanged
{
    private int count;
    public int Count
    {
        get => count;
        set
        {
            if (value == count) 
                return;

            count = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

【问题讨论】:

  • label1.DataBindings.Add("Text", a, "Count", true, DataSourceUpdateMode.OnPropertyChanged); (...) Task.Run(()=> BeginInvoke(new Action(() => a.Count++)));
  • 删除CheckForIllegalCrossThreadCalls = false;。永远不要使用它。

标签: c# winforms


【解决方案1】:

解决方案应该是这样的(未测试):

private readonly SynchronizationContext _syncContext = SynchronizationContext.Current;

private void button1_Click(object sender, EventArgs e)
{
    Task.Run(() => { 
        _syncContext.Post(() => {
            a.Count++;
        }); 
    }); //get error
}

【讨论】:

  • 已编辑,现在应该更好了。
猜你喜欢
  • 1970-01-01
  • 2015-03-20
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
相关资源
最近更新 更多