2012-04-20 57 views
1

我只想在另一個線程中更改窗口的背景。有兩個程序,一個是工作正確的,另一個拋出InvalidOperationException。使用由其他線程創建的對象

權代碼:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     Thread t = new Thread(new ParameterizedThreadStart(threadTest)); 
     t.Start(@"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"); 
    } 

    void threadTest(object obj) 
    { 
     string path = obj as string; 
     this.Dispatcher.Invoke(new Func<object>(() => this.Background = new 
    } 
} 

的錯誤代碼:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     Thread t = new Thread(new ParameterizedThreadStart(threadTest)); 
     t.Start(@"C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"); 
    } 

    void threadTest(object obj) 
    { 
     string path = obj as string; 
     //this.Dispatcher.Invoke(new Func<object>(() => this.Background = new ImageBrush(new BitmapImage(new Uri(path))))); 
     ImageBrush background = new ImageBrush(new BitmapImage(new Uri(path))); 
     this.Dispatcher.Invoke(new Func<object>(() => this.Background = background)); 
    } 
} 

不同,這些代碼之間是,錯誤代碼創建的子線程的圖像刷對象。 所以我的問題是:在wpf程序中,線程是否只能使用由自己的線程創建的對象? 感謝您的任何答覆。

回答

1

是的,你是對的。只有UI線程可以使用它創建的對象。因此,您可以使用Dispatcher將UI操作「排入」其正確的線程。

回答你的第二個問題,當然,有一種方法可以將對象「傳遞」到UI線程。如果你看到的BeginInvoke結構(調度員),它是:

public DispatcherOperation BeginInvoke(
    Delegate d, 
    params Object[] args 
) 

凡ARGS是params對象數組,還有就是你把PARAMS。

現在,如果您使用的是一些Freezable對象(例如某些圖像,畫筆,變換或幾何體),那麼在將其發送到UI線程之前,您需要object.Freeze();

+0

如果UI線程只能使用自己創建的對象,是否有任何方法讓其他線程通過對象到UI線程? – adream307 2012-04-21 06:17:51

+0

@ adream307當然有,請參閱我的編輯:) – 2012-04-21 14:28:46

0

是的,正確的,它不僅是關於WPF,但一般來說,關於Windows programming

您無法從與其自己不同的其他線程更新UI對象。

造成這種情況的原因很簡單,因爲必須保證消息泵送以及特別是交付到操作系統的目標控制。這對於使用SendMesage進行通信當然是有效的,但對於PostMessage也是如此。

0

如果你在一個單獨的線程上創建一個對象,你可以在gui線程上使用它,如果你先凍結它。見Freezable objects

相關問題