3

現在本番環境にあるプログラムに追加する必要があり、アーキテクチャをあまり変更できません。

メインスレッド(T1)-> GUI要素その他のスレッド(T2 ...)->計算要素(および外部イベント)。

FooT2で実行されているオブジェクトクラスがあります。Foosは、さまざまな外部イベントに基づいて作成されます。

さまざまなFooオブジェクトのプロパティを表示するだけの新しいフォームにDataGridを追加する必要があります。

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スレッドの問題が発生します(私が解決しようとしていること)

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 に答える