2012-11-01 106 views
1

需要對當前正在生產的程序進行添加,並且我無法真正做出很多體系結構更改。如何調用跨線程BindingList <T> in C#

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

有一個在T2上運行的對象類Foo。 Foos是根據各種外部事件創建的。

我需要添加一個DataGrid到一個新的窗體,它將只顯示不同的Foo對象的屬性。

Foo實現INotifyPropertyChanged

的winform GridForm具有BindingList<Foo> FooList對象。 GridView的數據綁定到它。

顯然,我在撥打NotifyPropertyChangedFoo 並且該功能無效時正在進行x線程調用。

我無法從主線程產生我的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線的問題(我試圖解決)

+0

我有點失去了你的問題。你可以提供一些代碼嗎? –

+0

爲什麼你不在T2中發生事件並在T1中捕獲事件? –

+0

oh bindingLIST。我就像「是所有T的綁定者T?」 :) –

回答

1

我想這就是你要求的...

改變你的INotifyPropertyChanged工具entation在富到:

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可以從兩個線程中引發都沒有問題。

related article您可能會發現教育或混亂:)沒有中間地帶:)

+0

謝謝。但是這個解決方案需要.Net 4.5。這是偉大的,但我運行4.0 - VS2010不支持4.5。任何想法在4.0? (我仍然upvoted它) – Sam

+0

我認爲你可以刪除[CallerMemberName]屬性,然後再試一次,我上面編輯。讓我知道它是否工作.. – user1416420

+0

我得到這個錯誤:不能轉換lambda表達式鍵入'System.Delegate',因爲它不是一個委託類型(在MainForm.Invoke) – Sam