数据绑定多线程应用程序?

数据绑定多线程应用程序?

问题描述:

以下代码是我的问题的简化版本:

The following code is the simplified version of my problem:

public partial class Form1 : Form
{
    BackgroundWorker bw;
    Class myClass = new Class();

    public Form1()
    {
        InitializeComponent();

        bw = new BackgroundWorker();
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        label1.DataBindings.Add("Text", myClass, "Text", true, DataSourceUpdateMode.Never);
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        myClass.Text = "Hi";
    }

    private void button1_Click(object sender, EventArgs e)
    {
        bw.RunWorkerAsync();
    }
}

public class Class : INotifyPropertyChanged
{
    private string _Text;

    private void SetText(string value)
    {
        if (_Text != value)
        {
            _Text = value;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public string Text
    {
        get { return _Text; }
        set { SetText(value); OnPropertyChanged(new PropertyChangedEventArgs("Text")); }
    }

    protected void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null) PropertyChanged(this, e);
    }
}

发生什么是当我点击button1调用 button1_Click label1 中的文本不更新。这是因为 label1.Text 属性在内部尝试从我的 BackgroundWorker 的线程中更改,内部导致一个例外。一般来说,解决这种问题最好的办法是什么?如果您必须从不同的线程更新我的 Class.Text 属性,但是还必须绑定一个控件,那么您将修改此代码的哪一部分?

What happens is that when I click the button1 (which invokes button1_Click) the text in label1 doesn't update. This is because the label1.Text property is internally trying to be changed from my BackgroundWorker's thread, which internally causes an exception. What would it be the best way, in general, to fix this kind of problem? Which part of this code would you change if you must update my Class.Text property from a different thread but must also have a control binded to it?

尝试这样:

//This is the handler to execute the thread.
void DoWork(object sender, EventArgs a) {

 Action updateControl = ()=>myClass.Text = "Blah";

 if(myForm.InvokeRequired) {

    myForm.Invoke( updateControl);

 }
 else {updateControl();}

此例程在后台工作线程上执行。

this routine executes on the background worker thread.