3

需要对当前正在生产的程序进行添加,而我实际上无法进行太多架构更改。

主线程 (T1) -> GUI 元素其他线程 (T2...) -> 计算元素(和外部事件)。

有一个对象类Foo在 T2 上运行。Foos 是根据各种外部事件创建的。

我需要将 DataGrid 添加到一个新表单,该表单将简单地显示不同 Foo 对象的属性。

Foo工具INotifyPropertyChanged

winformGridForm有一个BindingList<Foo> FooList 对象。GridView 的数据绑定到它。

显然,当我调用NotifyPropertyChanged我的时,我正在进行 x-thread 调用Foo ,但这不起作用。

我无法Foo从主线程生成对象,也无法在 Thread2 上创建表单。

关于如何调用主线程,我在这里摸不着头脑。

我确实有Foo-Brain一个引用主窗体的静态类(因此我可以获得 GUI 线程。)。问题是如何将这一切联系在一起。

有任何想法吗?

(我正在考虑复制Foo对象并在 GUI 线程上运行它们并包含FooList这些对象,但这似乎很笨拙且效率低下)。

谢谢。

PS。希望每个人都对桑迪好。

编辑:示例代码:

class Person : INotifyPropertyChanged // this is the object that will be updated from a
     //different thread; It will have the reference to the main form (GUI)
{
    public event PropertyChangedEventHandler PropertyChanged;
    string comments;  
    private Form1 mainForm = null;

    private void NotifyPropertyChanged(string name)
    {
        if (PropertyChanged == null) return;
        PropertyChanged(this, new PropertyChangedEventArgs(name));         
    }


    public Person(string comments, Form1 f) 
    {
        this.mainForm = f;
        this.comments = comments;
    }

    public string Comments 
    {
        get { return comments; }
        set
        {   comments = value;
            NotifyPropertyChanged("Comments");
        }
    }
}

GUI形式的代码:

private void Form1_Load(object sender, EventArgs e)
{
    gridControl.DataSource = gridDataList;
}

private void runmethread()
{
    Thread t = new Thread(anotherthread);
    t.Start();
}

private void anotherthread()
{
    gridDataList[0].Comments = "NEW THREAD";
}

private void button1_Click(object sender, EventArgs e)
{
    runmethread();
}

private void button2_Click(object sender, EventArgs e)
{
    gridDataList[0].Comments = "OLD THREAD";
}

显然 button1_click 会导致 x-thread 问题(我要解决的问题)

4

1 回答 1

3

我想这就是你要问的......

将 Foo 中的 INotifyPropertyChanged 实现更改为:

public class Foo: INotifyPropertyChanged
{

  public event PropertyChangedEventHandler PropertyChanged;

  private void NotifyPropertyChanged(String propertyName = "")
  {
      if (PropertyChanged != null)
      {
       if (mainForm.InvokeRequired)
       {
           mainForm.Invoke((MethodInvoker) delegate
           {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
           });
        }
        else
        {
           PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
        }
      }
  } 
}

这将确保无论何时发生 PropertyChanged 事件(以及在其运行期间的整个持续时间内),它都是 T1 将运行的唯一事件。因此,可以从两个线程中引发 PropertyChanged 没问题。

相关文章您可能会觉得有教育意义或令人困惑:) 没有中间立场:)

于 2012-11-01T06:17:30.533 回答